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

Merge branch 'master' into github-extension

This commit is contained in:
Elliott Stoneham 2016-07-07 16:34:14 +01:00
commit 2a28d5ba53
62 changed files with 1460 additions and 1545 deletions

View file

@ -0,0 +1,15 @@
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
const {
RSVP: { resolve }
} = Ember;
export default Base.extend({
restore(data) {
return resolve(data);
},
authenticate(data) {
return resolve(data);
}
});

View file

@ -0,0 +1,59 @@
import Ember from 'ember';
import Base from 'ember-simple-auth/authenticators/base';
import encodingUtil from '../utils/encoding';
import netUtil from '../utils/net';
import models from '../utils/model';
const {
isPresent,
RSVP: { resolve, reject },
inject: { service }
} = Ember;
export default Base.extend({
ajax: service(),
appMeta: service(),
restore(data) {
// TODO: verify authentication data
if (data) {
return resolve(data);
}
return reject();
},
authenticate(credentials) {
let domain = netUtil.getSubdomain();
let encoded;
if (typeof credentials === 'object') {
let { password, email } = credentials;
if (!isPresent(password) || !isPresent(email)) {
return Ember.RSVP.reject("invalid");
}
encoded = encodingUtil.Base64.encode(`${domain}:${email}:${password}`);
} else if (typeof credentials === 'string') {
encoded = credentials;
} else {
return Ember.RSVP.reject("invalid");
}
var headers = {
'Authorization': 'Basic ' + encoded
};
return this.get('ajax').post('public/authenticate', {
headers
});
},
invalidate() {
return resolve();
}
});

View file

@ -15,6 +15,7 @@ import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, { export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
userService: Ember.inject.service('user'), userService: Ember.inject.service('user'),
localStorage: Ember.inject.service(),
drop: null, drop: null,
users: [], users: [],
saveTemplate: { saveTemplate: {
@ -43,11 +44,12 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
if (this.get('isEditor')) { if (this.get('isEditor')) {
let self = this; let self = this;
let documentId = this.get('document.id'); let documentId = this.get('document.id');
let uploadUrl = this.session.appMeta.getUrl(`documents/${documentId}/attachments`); let url = this.get('appMeta.url');
let uploadUrl = `${url}/documents/${documentId}/attachments`;
let dzone = new Dropzone("#attachment-button > i", { let dzone = new Dropzone("#attachment-button > i", {
headers: { headers: {
'Authorization': 'Bearer ' + self.session.getSessionItem('token') 'Authorization': 'Bearer ' + self.get('localStorage').getSessionItem('session.session.authenticated.token')
}, },
url: uploadUrl, url: uploadUrl,
method: "post", method: "post",

View file

@ -16,6 +16,7 @@ import TooltipMixin from '../../mixins/tooltip';
export default Ember.Component.extend(NotifierMixin, TooltipMixin, { export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
sectionService: Ember.inject.service('section'), sectionService: Ember.inject.service('section'),
appMeta: Ember.inject.service(),
/* Parameters */ /* Parameters */
document: null, document: null,
// pages: [], // pages: [],

View file

@ -13,6 +13,7 @@ import Ember from 'ember';
export default Ember.Component.extend({ export default Ember.Component.extend({
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
appMeta: Ember.inject.service(),
users: [], users: [],
folders: [], folders: [],
folder: {}, folder: {},
@ -23,7 +24,7 @@ export default Ember.Component.extend({
permissions: {}, permissions: {},
getDefaultInvitationMessage() { getDefaultInvitationMessage() {
return "Hey there, I am sharing the " + this.folder.get('name') + " (in " + this.session.appMeta.title + ") with you so we can both access the same documents."; return "Hey there, I am sharing the " + this.folder.get('name') + " (in " + this.get("appMeta.title") + ") with you so we can both access the same documents.";
}, },
willRender() { willRender() {

View file

@ -13,20 +13,25 @@ import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier'; import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip'; import TooltipMixin from '../../mixins/tooltip';
const {
computed
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, { export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
templateService: Ember.inject.service('template'), templateService: Ember.inject.service('template'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
session: Ember.inject.service(),
folder: {}, folder: {},
busy: false, busy: false,
importedDocuments: [], importedDocuments: [],
savedTemplates: [], savedTemplates: [],
isFolderOwner: false, isFolderOwner: computed.equal('folder.userId', 'session.user.id'),
moveFolderId: "", moveFolderId: "",
didReceiveAttrs() { didReceiveAttrs() {
this.set('isFolderOwner', this.get('folder.userId') === this.session.user.id); this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id"));
let self = this; let self = this;

View file

@ -13,12 +13,14 @@ import Ember from 'ember';
import NotifierMixin from '../../mixins/notifier'; import NotifierMixin from '../../mixins/notifier';
export default Ember.Component.extend(NotifierMixin, { export default Ember.Component.extend(NotifierMixin, {
localStorage: Ember.inject.service(),
tagName: 'span', tagName: 'span',
selectedTemplate: { selectedTemplate: {
id: "0" id: "0"
}, },
canEditTemplate: "", canEditTemplate: "",
drop: null, drop: null,
appMeta: Ember.inject.service(),
didReceiveAttrs() { didReceiveAttrs() {
this.send('setTemplate', this.get('savedTemplates')[0]); this.send('setTemplate', this.get('savedTemplates')[0]);
@ -71,13 +73,14 @@ export default Ember.Component.extend(NotifierMixin, {
let self = this; let self = this;
let folderId = this.get('folder.id'); let folderId = this.get('folder.id');
let importUrl = this.session.appMeta.getUrl('import/folder/' + folderId); let url = this.get('appMeta.url');
let importUrl = `${url}/import/folder/${folderId}`;
Dropzone.options.uploadDocuments = false; Dropzone.options.uploadDocuments = false;
let dzone = new Dropzone("#upload-documents", { let dzone = new Dropzone("#upload-documents", {
headers: { headers: {
'Authorization': 'Bearer ' + self.session.getSessionItem('token') 'Authorization': 'Bearer ' + self.get('localStorage').getSessionItem('session.session.authenticated.token')
}, },
url: importUrl, url: importUrl,
method: "post", method: "post",

View file

@ -15,12 +15,13 @@ import netUtil from '../../utils/net';
export default Ember.Component.extend({ export default Ember.Component.extend({
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
folder: null, folder: null,
appMeta: Ember.inject.service(),
didInitAttrs() { didInitAttrs() {
let self = this; if (this.get("session.authenticated")) {
if (this.session.authenticated) { this.get("session.user.accounts").forEach((account)=>{
this.session.user.accounts.forEach(function(account) { // TODO: do not mutate account.active here
account.active = account.orgId === self.session.appMeta.orgId; account.active = account.orgId === this.get("appMeta.orgId");
}); });
} }
}, },

View file

@ -13,6 +13,7 @@ import Ember from 'ember';
export default Ember.Component.extend({ export default Ember.Component.extend({
pageBody: "", pageBody: "",
appMeta: Ember.inject.service(),
didReceiveAttrs() { didReceiveAttrs() {
this.set('pageBody', this.get('meta.rawBody')); this.set('pageBody', this.get('meta.rawBody'));
@ -76,7 +77,7 @@ export default Ember.Component.extend({
}; };
if (typeof tinymce === 'undefined') { if (typeof tinymce === 'undefined') {
$.getScript(this.session.appMeta.getBaseUrl("tinymce/tinymce.min.js?v=430"), function() { $.getScript(this.get("appMeta").getBaseUrl("tinymce/tinymce.min.js?v=430"), function() {
window.tinymce.dom.Event.domLoaded = true; window.tinymce.dom.Event.domLoaded = true;
tinymce.baseURL = "//" + window.location.host + "/tinymce"; tinymce.baseURL = "//" + window.location.host + "/tinymce";
tinymce.suffix = ".min"; tinymce.suffix = ".min";

View file

@ -15,9 +15,15 @@ export default Ember.Mixin.create({
tooltips: [], tooltips: [],
addTooltip(elem) { addTooltip(elem) {
if(elem == null) {
return;
}
let t = new Tooltip({ let t = new Tooltip({
target: elem target: elem
}); });
let tt = this.get('tooltips'); let tt = this.get('tooltips');
tt.push(t); tt.push(t);
}, },

View file

@ -4,6 +4,8 @@ export default Ember.Controller.extend({
email: "", email: "",
password: "", password: "",
invalidCredentials: false, invalidCredentials: false,
session: Ember.inject.service('session'),
audit: Ember.inject.service('audit'),
reset() { reset() {
this.setProperties({ this.setProperties({
@ -20,23 +22,15 @@ export default Ember.Controller.extend({
actions: { actions: {
login() { login() {
let self = this;
let creds = this.getProperties('email', 'password'); let creds = this.getProperties('email', 'password');
this.session.login(creds).then(function() { this.get('session').authenticate('authenticator:documize', creds)
self.set('invalidCredentials', false); .then((response) => {
self.audit.record("logged-in"); this.get('audit').record("logged-in");
this.transitionToRoute('folders.folder');
var previousTransition = self.session.get('previousTransition'); return response;
}).catch(() => {
if (previousTransition) { this.set('invalidCredentials', true);
previousTransition.retry();
self.session.set('previousTransition', null);
} else {
self.transitionToRoute('folders.folder');
}
}, function() {
self.set('invalidCredentials', true);
}); });
} }
} }

View file

@ -2,14 +2,17 @@ import Ember from 'ember';
import config from 'documize/config/environment'; import config from 'documize/config/environment';
export default Ember.Route.extend({ export default Ember.Route.extend({
session: Ember.inject.service(),
appMeta: Ember.inject.service(),
activate: function(){ activate: function(){
this.session.logout(); this.get('session').invalidate();
this.audit.record("logged-in"); this.audit.record("logged-in");
this.audit.stop(); this.audit.stop();
if (config.environment === 'test') { if (config.environment === 'test') {
this.transitionTo('auth.login'); this.transitionTo('auth.login');
}else{ }else{
window.document.location = this.session.appMeta.allowAnonymousAccess ? "/" : "/auth/login"; window.document.location = this.get("appMeta.allowAnonymousAccess") ? "/" : "/auth/login";
} }
} }
}); });

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function(params) { model: function(params) {
this.set('folderId', params.id); this.set('folderId', params.id);
this.set('slug', params.slug); this.set('slug', params.slug);

View file

@ -1,23 +1,14 @@
import Ember from 'ember'; import Ember from 'ember';
export default Ember.Route.extend({ export default Ember.Route.extend({
beforeModel() { session: Ember.inject.service(),
this.session.clearSession();
},
model(params) { model({ token }) {
let token = params.token; this.get("session").authenticate('authenticator:documize', token)
.then(() => {
if (is.undefined(token) || is.null(token) || token.length === 0) { this.transitionTo('folders.folder');
return; }, () => {
} this.transitionTo('auth.login');
let self = this;
this.session.sso(decodeURIComponent(token)).then(function() {
self.transitionTo('folders.folder');
}, function() {
self.transitionTo('auth.login');
console.log(">>>>> Documize SSO failure"); console.log(">>>>> Documize SSO failure");
}); });
}, },

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
beforeModel() { beforeModel() {

View file

@ -1,16 +1,20 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
orgService: Ember.inject.service('organization'), orgService: Ember.inject.service('organization'),
appMeta: Ember.inject.service(),
session: Ember.inject.service(),
beforeModel() { beforeModel() {
if (!this.session.isAdmin) { if (!this.get("session.isAdmin")) {
this.transitionTo('auth.login'); this.transitionTo('auth.login');
} }
}, },
model() { model() {
return this.get('orgService').getOrg(this.session.appMeta.get('orgId')); let orgId = this.get("appMeta.orgId");
return this.get('orgService').getOrg(orgId);
}, },
activate() { activate() {

View file

@ -1,8 +1,8 @@
/*global is*/ /*global is*/
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend( export default Ember.Route.extend(AuthenticatedRouteMixin, {
{
beforeModel: function(transition) beforeModel: function(transition)
{ {
if (is.equal(transition.targetName, 'customize.index')) { if (is.equal(transition.targetName, 'customize.index')) {

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
userService: Ember.inject.service('user'), userService: Ember.inject.service('user'),
beforeModel: function() { beforeModel: function() {

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),

View file

@ -1,7 +1,8 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
// import models from '../../../utils/model'; // import models from '../../../utils/model';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
userService: Ember.inject.service('user'), userService: Ember.inject.service('user'),

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
model: function(params) { model: function(params) {

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
sectionService: Ember.inject.service('section'), sectionService: Ember.inject.service('section'),

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
documentService: Ember.inject.service('document'), documentService: Ember.inject.service('document'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),

View file

@ -1,7 +1,13 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ const {
isPresent
} = Ember;
export default Ember.Route.extend(AuthenticatedRouteMixin, {
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
localStorage: Ember.inject.service(),
folder: {}, folder: {},
model: function () { model: function () {
@ -9,45 +15,49 @@ export default Ember.Route.extend({
}, },
afterModel: function (model) { afterModel: function (model) {
let self = this;
if (is.empty(this.paramsFor('folders.folder'))) { let params = this.paramsFor('folders.folder');
var lastFolder = this.session.getSessionItem("folder");
if (is.not.undefined(lastFolder)) { if (is.empty(params)) {
this.get('folderService').getFolder(lastFolder).then(function(folder) { let lastFolder = this.get('localStorage').getSessionItem("folder");
if (is.undefined(folder) || is.null(folder)) {
self.transitionTo('auth.login'); //If folder lastFolder is defined
} if (isPresent(lastFolder)) {
self.folder = folder; return this.get('folderService').getFolder(lastFolder).then((folder) => {
self.transitionTo('folders.folder', folder.get('id'), folder.get('slug')); //if Response is null or undefined redirect to login else transitionTo dashboard
}, function() { if (Ember.isNone(folder)) {
if (model.length > 0) { this.transitionTo('auth.login');
var folder = model[0];
self.folder = folder;
self.transitionTo('folders.folder', folder.get('id'), folder.get('slug'));
} else {
self.transitionTo('auth.login');
} }
Ember.set(this, 'folder', folder);
this.transitionTo('folders.folder', folder.get('id'), folder.get('slug'));
}).catch(() => {
//if there was an error redirect to login
this.transitionTo('auth.login');
}); });
} else { }
// If model has any folders redirect to dashboard
if (model.length > 0) { if (model.length > 0) {
var folder = model[0]; let folder = model[0];
self.folder = folder; Ember.set(this, 'folder', folder);
self.transitionTo('folders.folder', folder.get('id'), folder.get('slug')); this.transitionTo('folders.folder', folder.get('id'), folder.get('slug'));
} else }
{
// has no folders, create default folder // has no folders, create default folder
this.get('folderService').add({ name: "My Space" }).then(function(folder) { return this.get('folderService').add({ name: "My Space" }).then((folder) => {
self.folder = folder; Ember.set(this, 'folder', folder);
self.transitionTo('folders.folder', folder.get('id'), folder.get('slug')); this.transitionTo('folders.folder', folder.get('id'), folder.get('slug'));
}); });
} }
}
} else { //If folder route has params
var folderId = this.paramsFor('folders.folder').folder_id; if (isPresent(params)) {
this.get('folderService').getFolder(folderId).then(function(folder) {
self.folder = folder; let folderId = this.paramsFor('folders.folder').folder_id;
return this.get('folderService').getFolder(folderId).then((folder) => {
Ember.set(this, 'folder', folder);
}); });
} }

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import models from '../../../utils/model'; import models from '../../../utils/model';
import NotifierMixin from '../../../mixins/notifier'; import NotifierMixin from '../../../mixins/notifier';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(NotifierMixin, { export default Ember.Route.extend(NotifierMixin, {
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
@ -112,7 +113,8 @@ export default Ember.Route.extend(NotifierMixin, {
onPermission: function (folder, message, permissions) { onPermission: function (folder, message, permissions) {
var self = this; var self = this;
var data = permissions.map(function(obj){ return obj.getProperties('orgId', 'folderId' , 'userId', 'canEdit', 'canView'); }); var data = permissions.map(function (obj) {
return obj.getProperties('orgId', 'folderId', 'userId', 'canEdit', 'canView'); });
var payload = { Message: message, Roles: data }; var payload = { Message: message, Roles: data };
this.get('folderService').savePermissions(folder.get('id'), payload).then(function () { this.get('folderService').savePermissions(folder.get('id'), payload).then(function () {

View file

@ -1,6 +1,7 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
beforeModel: function() { beforeModel: function() {
this.transitionTo('folders'); this.transitionTo('folders');

View file

@ -3,6 +3,7 @@ import Ember from 'ember';
export default Ember.Controller.extend({ export default Ember.Controller.extend({
userService: Ember.inject.service('user'), userService: Ember.inject.service('user'),
password: { password: "", confirmation: ""}, password: { password: "", confirmation: ""},
session: Ember.inject.service(),
actions: { actions: {
save: function() { save: function() {

View file

@ -1,17 +1,21 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin, {
userService: Ember.inject.service('user'), userService: Ember.inject.service('user'),
folderService: Ember.inject.service('folder'), folderService: Ember.inject.service('folder'),
session: Ember.inject.service(),
beforeModel: function() { beforeModel: function() {
if (!this.session.authenticated) { if (!this.get("session").authenticated) {
this.transitionTo('auth.login'); this.transitionTo('auth.login');
} }
}, },
model: function() { model: function() {
return this.get('userService').getUser(this.session.user.id); return this.get('userService').getUser(this.get("session.session.authenticated.user.id"));
debugger;
}, },
afterModel: function(model) { afterModel: function(model) {

View file

@ -1,5 +1,5 @@
// Copyright (c) 2015 Documize Inc. // Copyright (c) 2015 Documize Inc.
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin);
});

View file

@ -1,4 +1,4 @@
import Ember from 'ember'; import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend({ export default Ember.Route.extend(AuthenticatedRouteMixin);
});

View file

@ -10,30 +10,22 @@
// https://documize.com // https://documize.com
import Ember from 'ember'; import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
import netUtil from '../utils/net'; import netUtil from '../utils/net';
export default Ember.Route.extend({ const {
userService: Ember.inject.service('user'), inject: { service }
sessionService: Ember.inject.service('session'), } = Ember;
transitioning: false,
beforeModel: function(transition) { export default Ember.Route.extend(ApplicationRouteMixin, {
let self = this; appMeta: service(),
let session = this.get('sessionService'); session: service(),
beforeModel() {
// Session ready? return this.get('appMeta').boot().then(data => {
return session.boot().then(function() { if (data.allowAnonymousAccess) {
// Need to authenticate? return this.get('session').authenticate('authenticator:anonymous', data);
if (!session.get("appMeta.allowAnonymousAccess") && !session.get("authenticated") &&
is.not.startWith(transition.targetName, 'auth.')) {
if (!self.transitioning) {
session.set('previousTransition', transition);
self.set('transitioning', true);
}
transition.abort();
self.transitionTo('auth.login');
} }
return;
}); });
}, },

25
app/app/services/ajax.js Normal file
View file

@ -0,0 +1,25 @@
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: Ember.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;
}
})
});

View file

@ -0,0 +1,45 @@
import Ember from 'ember';
import config from '../config/environment';
const {
String: { htmlSafe },
RSVP: { resolve },
inject: { service }
} = Ember;
export default Ember.Service.extend({
ajax: service(),
url: `${config.apiHost}/${config.apiNamespace}`,
orgId: '',
title: '',
version: '',
message: '',
allowAnonymousAccess: false,
getBaseUrl(endpoint) {
return [this.get('host'), endpoint].join('/');
},
boot() {
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.setProperites({
title: htmlSafe("Documize Setup"),
allowAnonymousAccess: false
});
return resolve();
}
return this.get('ajax').request('public/meta')
.then((response) => {
this.setProperties(response);
return response;
});
}
});

View file

@ -18,9 +18,7 @@ export default Ember.Service.extend({
// Returns document model for specified document id. // Returns document model for specified document id.
getDocument(documentId) { getDocument(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}`); return this.get('ajax').request(`documents/${documentId}`, {
return this.get('ajax').request(url, {
method: "GET" method: "GET"
}).then((response) => { }).then((response) => {
return models.DocumentModel.create(response); return models.DocumentModel.create(response);
@ -29,10 +27,7 @@ export default Ember.Service.extend({
// Returns all documents for specified folder. // Returns all documents for specified folder.
getAllByFolder(folderId) { getAllByFolder(folderId) {
let appMeta = this.get('sessionService.appMeta'); return this.get('ajax').request(`documents?folder=${folderId}`, {
let url = appMeta.getUrl(`documents?folder=${folderId}`);
return this.get('ajax').request(url, {
method: "GET" method: "GET"
}).then((response) => { }).then((response) => {
let documents = Ember.ArrayProxy.create({ let documents = Ember.ArrayProxy.create({
@ -50,9 +45,7 @@ export default Ember.Service.extend({
// getDocumentsByTag returns all documents for specified tag (not folder!). // getDocumentsByTag returns all documents for specified tag (not folder!).
getAllByTag(tag) { getAllByTag(tag) {
let url = this.get('sessionService').appMeta.getUrl(`documents?filter=tag&tag=${tag}`); return this.get('ajax').request(`documents?filter=tag&tag=${tag}`, {
return this.get('ajax').request(url, {
method: "GET" method: "GET"
}).then((response) => { }).then((response) => {
let documents = Ember.ArrayProxy.create({ let documents = Ember.ArrayProxy.create({
@ -71,16 +64,15 @@ export default Ember.Service.extend({
// saveDocument updates an existing document record. // saveDocument updates an existing document record.
save(doc) { save(doc) {
let id = doc.get('id'); let id = doc.get('id');
let url = this.get('sessionService').appMeta.getUrl(`documents/${id}`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${id}`, {
method: 'PUT', method: 'PUT',
data: JSON.stringify(doc) data: JSON.stringify(doc)
}); });
}, },
getBatchedPages: function(documentId, payload) { getBatchedPages: function(documentId, payload) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/batch"); let url = `documents/${documentId}/pages/batch`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'POST', method: 'POST',
@ -95,7 +87,7 @@ export default Ember.Service.extend({
}, },
changePageSequence: function(documentId, payload) { changePageSequence: function(documentId, payload) {
var url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/sequence"); let url = `documents/${documentId}/pages/sequence`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: JSON.stringify(payload), data: JSON.stringify(payload),
@ -104,7 +96,7 @@ export default Ember.Service.extend({
}, },
changePageLevel(documentId, payload) { changePageLevel(documentId, payload) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/level"); let url = `documents/${documentId}/pages/level`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: JSON.stringify(payload), data: JSON.stringify(payload),
@ -113,7 +105,7 @@ export default Ember.Service.extend({
}, },
deleteDocument: function(documentId) { deleteDocument: function(documentId) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId); let url = `documents/${documentId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'DELETE' method: 'DELETE'
@ -122,7 +114,7 @@ export default Ember.Service.extend({
updatePage: function(documentId, pageId, payload, skipRevision) { updatePage: function(documentId, pageId, payload, skipRevision) {
var revision = skipRevision ? "?r=true" : "?r=false"; var revision = skipRevision ? "?r=true" : "?r=false";
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId + revision); let url = `documents/${documentId}/pages/${pageId}${revision}`
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'PUT', method: 'PUT',
@ -133,7 +125,7 @@ export default Ember.Service.extend({
// addPage inserts new page to an existing document. // addPage inserts new page to an existing document.
addPage: function(documentId, payload) { addPage: function(documentId, payload) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages"); let url = `documents/${documentId}/pages`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: JSON.stringify(payload), data: JSON.stringify(payload),
@ -143,7 +135,7 @@ export default Ember.Service.extend({
// Nukes multiple pages from the document. // Nukes multiple pages from the document.
deletePages: function(documentId, pageId, payload) { deletePages: function(documentId, pageId, payload) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId); let url = `documents/${documentId}/pages/${pageId}`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: JSON.stringify(payload), data: JSON.stringify(payload),
@ -153,7 +145,7 @@ export default Ember.Service.extend({
// Nukes a single page from the document. // Nukes a single page from the document.
deletePage: function(documentId, pageId) { deletePage: function(documentId, pageId) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId); let url = `documents/${documentId}/pages/${pageId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'DELETE' method: 'DELETE'
@ -161,7 +153,7 @@ export default Ember.Service.extend({
}, },
getPageRevisions(documentId, pageId) { getPageRevisions(documentId, pageId) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId + "/revisions"); let url = `documents/${documentId}/pages/${pageId}/revisions`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "GET" method: "GET"
@ -169,7 +161,7 @@ export default Ember.Service.extend({
}, },
getPageRevisionDiff(documentId, pageId, revisionId) { getPageRevisionDiff(documentId, pageId, revisionId) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId + "/revisions/" + revisionId); let url = `documents/${documentId}/pages/${pageId}/revisions/${revisionId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "GET", method: "GET",
@ -178,7 +170,7 @@ export default Ember.Service.extend({
}, },
rollbackPage(documentId, pageId, revisionId) { rollbackPage(documentId, pageId, revisionId) {
let url = this.get('sessionService').appMeta.getUrl("documents/" + documentId + "/pages/" + pageId + "/revisions/" + revisionId); let url = `documents/${documentId}/pages/${pageId}/revisions/${revisionId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "POST" method: "POST"
@ -187,18 +179,16 @@ export default Ember.Service.extend({
// document meta referes to number of views, edits, approvals, etc. // document meta referes to number of views, edits, approvals, etc.
getMeta(documentId) { getMeta(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/meta`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/meta`, {
method: "GET" method: "GET"
}); });
}, },
// Returns all pages without the content // Returns all pages without the content
getTableOfContents(documentId) { getTableOfContents(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/pages?content=0`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/pages?content=0`, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
let data = []; let data = [];
@ -212,9 +202,8 @@ export default Ember.Service.extend({
// Returns all document pages with content // Returns all document pages with content
getPages(documentId) { getPages(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/pages`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/pages`, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
let pages = []; let pages = [];
@ -229,9 +218,8 @@ export default Ember.Service.extend({
// Returns document page with content // Returns document page with content
getPage(documentId, pageId) { getPage(documentId, pageId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/pages/${pageId}`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/pages/${pageId}`, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
let page = models.PageModel.create(response); let page = models.PageModel.create(response);
@ -241,9 +229,8 @@ export default Ember.Service.extend({
// Returns document page meta object // Returns document page meta object
getPageMeta(documentId, pageId) { getPageMeta(documentId, pageId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/pages/${pageId}/meta`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/pages/${pageId}/meta`, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
let meta = models.PageMetaModel.create(response); let meta = models.PageMetaModel.create(response);
@ -253,9 +240,8 @@ export default Ember.Service.extend({
// document attachments without the actual content // document attachments without the actual content
getAttachments(documentId) { getAttachments(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/attachments`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/attachments`, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
let data = []; let data = [];
@ -268,9 +254,8 @@ export default Ember.Service.extend({
// nuke an attachment // nuke an attachment
deleteAttachment(documentId, attachmentId) { deleteAttachment(documentId, attachmentId) {
let url = this.get('sessionService').appMeta.getUrl(`documents/${documentId}/attachments/${attachmentId}`);
return this.get('ajax').request(url, { return this.get('ajax').request(`documents/${documentId}/attachments/${attachmentId}`, {
method: 'DELETE' method: 'DELETE'
}); });
}, },

View file

@ -13,9 +13,15 @@ import Ember from 'ember';
import models from '../utils/model'; import models from '../utils/model';
import BaseService from '../services/base'; import BaseService from '../services/base';
const {
get
} = Ember;
export default BaseService.extend({ export default BaseService.extend({
sessionService: Ember.inject.service('session'), sessionService: Ember.inject.service('session'),
ajax: Ember.inject.service(), ajax: Ember.inject.service(),
localStorage: Ember.inject.service(),
// selected folder // selected folder
currentFolder: null, currentFolder: null,
@ -23,10 +29,8 @@ export default BaseService.extend({
// Add a new folder. // Add a new folder.
add(folder) { add(folder) {
let appMeta = this.get('sessionService.appMeta');
let url = appMeta.getUrl(`folders`);
return this.get('ajax').post(url, { return this.get('ajax').post(`folders`, {
contentType: 'json', contentType: 'json',
data: JSON.stringify(folder) data: JSON.stringify(folder)
}).then((folder)=>{ }).then((folder)=>{
@ -37,10 +41,8 @@ export default BaseService.extend({
// Returns folder model for specified folder id. // Returns folder model for specified folder id.
getFolder(id) { getFolder(id) {
let appMeta = this.get('sessionService.appMeta');
let url = appMeta.getUrl(`folders/${id}`);
return this.get('ajax').request(url, { return this.get('ajax').request(`folders/${id}`, {
method: 'GET' method: 'GET'
}).then((response)=>{ }).then((response)=>{
let folder = models.FolderModel.create(response); let folder = models.FolderModel.create(response);
@ -64,9 +66,8 @@ export default BaseService.extend({
// Updates an existing folder record. // Updates an existing folder record.
save(folder) { save(folder) {
let id = folder.get('id'); let id = folder.get('id');
let url = this.get('sessionService').appMeta.getUrl(`folders/${id}`);
return this.get('ajax').request(url, { return this.get('ajax').request(`folders/${id}`, {
method: 'PUT', method: 'PUT',
contentType: 'json', contentType: 'json',
data: JSON.stringify(folder) data: JSON.stringify(folder)
@ -74,7 +75,7 @@ export default BaseService.extend({
}, },
remove: function(folderId, moveToId) { remove: function(folderId, moveToId) {
var url = this.get('sessionService').appMeta.getUrl('folders/' + folderId + "/move/" + moveToId); let url = `folders/${folderId}/move/${moveToId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'DELETE' method: 'DELETE'
@ -82,7 +83,7 @@ export default BaseService.extend({
}, },
onboard: function(folderId, payload) { onboard: function(folderId, payload) {
var url = this.get('sessionService').appMeta.getUrl('public/share/' + folderId); let url = `public/share/${folderId}`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
contentType: "application/json", contentType: "application/json",
@ -92,9 +93,7 @@ export default BaseService.extend({
// getProtectedFolderInfo returns non-private folders and who has access to them. // getProtectedFolderInfo returns non-private folders and who has access to them.
getProtectedFolderInfo: function() { getProtectedFolderInfo: function() {
var url = this.get('sessionService').appMeta.getUrl('folders?filter=viewers'); return this.get('ajax').request(`folders?filter=viewers`, {
return this.get('ajax').request(url, {
method: "GET" method: "GET"
}).then((response)=>{ }).then((response)=>{
let data = []; let data = [];
@ -108,10 +107,8 @@ export default BaseService.extend({
// reloads and caches folders. // reloads and caches folders.
reload() { reload() {
let appMeta = this.get('sessionService.appMeta');
let url = appMeta.getUrl(`folders`);
return this.get('ajax').request(url, { return this.get('ajax').request(`folders`, {
method: "GET" method: "GET"
}).then((response)=>{ }).then((response)=>{
let data = []; let data = [];
@ -125,9 +122,8 @@ export default BaseService.extend({
// so who can see/edit this folder? // so who can see/edit this folder?
getPermissions(folderId) { getPermissions(folderId) {
let url = this.get('sessionService').appMeta.getUrl(`folders/${folderId}/permissions`);
return this.get('ajax').request(url, { return this.get('ajax').request(`folders/${folderId}/permissions`, {
method: "GET" method: "GET"
}).then((response)=>{ }).then((response)=>{
let data = []; let data = [];
@ -141,9 +137,8 @@ export default BaseService.extend({
// persist folder permissions // persist folder permissions
savePermissions(folderId, payload) { savePermissions(folderId, payload) {
let url = this.get('sessionService').appMeta.getUrl(`folders/${folderId}/permissions`);
return this.get('ajax').request(url, { return this.get('ajax').request(`folders/${folderId}/permissions`, {
method: 'PUT', method: 'PUT',
contentType: 'json', contentType: 'json',
data: JSON.stringify(payload) data: JSON.stringify(payload)
@ -152,9 +147,8 @@ export default BaseService.extend({
// share this folder with new users! // share this folder with new users!
share(folderId, invitation) { share(folderId, invitation) {
let url = this.get('sessionService').appMeta.getUrl(`folders/${folderId}/invitation`);
return this.get('ajax').post(url, { return this.get('ajax').post(`folders/${folderId}/invitation`, {
contentType: 'json', contentType: 'json',
data: JSON.stringify(invitation) data: JSON.stringify(invitation)
}); });
@ -167,15 +161,15 @@ export default BaseService.extend({
} }
this.set('currentFolder', folder); this.set('currentFolder', folder);
this.get('sessionService').storeSessionItem("folder", folder.get('id')); this.get('localStorage').storeSessionItem("folder", get(folder, 'id'));
this.set('canEditCurrentFolder', false); this.set('canEditCurrentFolder', false);
let userId = this.get('sessionService').user.get('id'); let userId = this.get('sessionService.user.id');
if (userId === "") { if (userId === "") {
userId = "0"; userId = "0";
} }
let url = this.get('sessionService').appMeta.getUrl('users/' + userId + "/permissions"); let url = `users/${userId}/permissions`;
return this.get('ajax').request(url).then((folderPermissions) => { return this.get('ajax').request(url).then((folderPermissions) => {
// safety check // safety check
@ -206,7 +200,7 @@ export default BaseService.extend({
} }
}); });
Ember.run(() => { Ember.run(() => {
this.set('canEditCurrentFolder', canEdit && this.get('sessionService').authenticated); this.set('canEditCurrentFolder', canEdit && this.get('sessionService.authenticated'));
}); });
}); });
}, },

View file

@ -0,0 +1,16 @@
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];
}
});

View file

@ -15,12 +15,11 @@ import models from '../utils/model';
export default Ember.Service.extend({ export default Ember.Service.extend({
sessionService: Ember.inject.service('session'), sessionService: Ember.inject.service('session'),
ajax: Ember.inject.service(), ajax: Ember.inject.service(),
appMeta: Ember.inject.service(),
// Returns attributes for specified org id. // Returns attributes for specified org id.
getOrg(id) { getOrg(id) {
let url = this.get('sessionService').appMeta.getUrl(`organizations/${id}`); return this.get('ajax').request(`organizations/${id}`, {
return this.get('ajax').request(url, {
method: 'GET' method: 'GET'
}).then((response) =>{ }).then((response) =>{
let org = models.OrganizationModel.create(response); let org = models.OrganizationModel.create(response);
@ -31,13 +30,13 @@ export default Ember.Service.extend({
// Updates an existing organization record. // Updates an existing organization record.
save(org) { save(org) {
let id = org.get('id'); let id = org.get('id');
let url = this.get('sessionService').appMeta.getUrl(`organizations/${id}`);
// refresh on-screen data this.get('appMeta').setProperties({
this.get('sessionService').get('appMeta').setSafe('message', org.message); message: org.message,
this.get('sessionService').get('appMeta').setSafe('title', org.title); title: org.title
});
return this.get('ajax').request(url, { return this.get('ajax').request(`organizations/${id}`, {
method: 'PUT', method: 'PUT',
data: JSON.stringify(org) data: JSON.stringify(org)
}); });

View file

@ -17,7 +17,7 @@ export default Ember.Service.extend({
// getUsers returns all users for organization. // getUsers returns all users for organization.
find(keywords) { find(keywords) {
let url = this.get('sessionService').appMeta.getUrl("search?keywords=" + encodeURIComponent(keywords)); let url = "search?keywords=" + encodeURIComponent(keywords);
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "GET" method: "GET"

View file

@ -19,9 +19,7 @@ export default BaseService.extend({
// Returns all available sections. // Returns all available sections.
getAll() { getAll() {
let url = this.get('sessionService').appMeta.getUrl(`sections`); return this.get('ajax').request(`sections`,{
return this.get('ajax').request(url,{
method: 'GET' method: 'GET'
}).then((response)=>{ }).then((response)=>{
let data = []; let data = [];
@ -38,8 +36,7 @@ export default BaseService.extend({
fetch(page, method, data) { fetch(page, method, data) {
let documentId = page.get('documentId'); let documentId = page.get('documentId');
let section = page.get('contentType'); let section = page.get('contentType');
let endpoint = `sections?documentID=${documentId}&section=${section}&method=${method}`; let url = `sections?documentID=${documentId}&section=${section}&method=${method}`;
let url = this.get('sessionService').appMeta.getUrl(endpoint);
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: JSON.stringify(data), data: JSON.stringify(data),
@ -49,7 +46,7 @@ export default BaseService.extend({
// Did any dynamic sections change? Fetch and send up for rendering? // Did any dynamic sections change? Fetch and send up for rendering?
refresh(documentId) { refresh(documentId) {
let url = this.get('sessionService').appMeta.getUrl(`sections/refresh?documentID=${documentId}`); let url = `sections/refresh?documentID=${documentId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'GET' method: 'GET'

View file

@ -10,189 +10,38 @@
// https://documize.com // https://documize.com
import Ember from 'ember'; import Ember from 'ember';
import encodingUtil from '../utils/encoding';
import netUtil from '../utils/net';
import models from '../utils/model'; import models from '../utils/model';
import SimpleAuthSession from 'ember-simple-auth/services/session';
const {
inject: { service },
computed: { oneWay, or, notEmpty },
computed
} = Ember;
export default SimpleAuthSession.extend({
ajax: service(),
appMeta: service(),
export default Ember.Service.extend({
ready: false,
appMeta: null,
isMac: false, isMac: false,
isMobile: false, isMobile: false,
previousTransition: null, authenticated: notEmpty('user.id'),
user: null, isAdmin: oneWay('user.admin'),
authenticated: false, isEditor: or('user.admin', 'user.editor'),
folderPermissions: null,
currentFolder: null,
ajax: Ember.inject.service(),
isAdmin: function() {
if (this.authenticated && is.not.null(this.user) && this.user.id !== "") {
return this.user.admin;
}
return false;
}.property('user'),
isEditor: function() {
if (this.authenticated && is.not.null(this.user) && this.user.id !== "") {
return this.user.editor || this.user.admin;
}
return false;
}.property('user'),
// Boot up
init: function () { init: function () {
this.set('user', models.UserModel.create());
this.appMeta = models.AppMeta.create();
this.set('isMac', is.mac()); this.set('isMac', is.mac());
this.set('isMobile', is.mobile()); this.set('isMobile', is.mobile());
}, },
// Authentication user: computed('isAuthenticated', 'session.content.authenticated.user', function () {
login: function(credentials) { if (this.get('isAuthenticated')) {
let url = this.appMeta.getUrl('public/authenticate'); let user = this.get('session.content.authenticated.user') || { id: '' };
let domain = netUtil.getSubdomain(); return models.UserModel.create(user);
this.clearSession();
if (is.empty(credentials.email) || is.empty(credentials.password)) {
return Ember.RSVP.reject("invalid");
} }
var encoded = encodingUtil.Base64.encode(domain + ":" + credentials.email + ":" + credentials.password); }),
var headers = {
'Authorization': 'Basic ' + encoded
};
return this.get('ajax').post(url, { folderPermissions: null,
headers currentFolder: null
}).then((response)=>{
this.setSession(response.token, models.UserModel.create(response.user));
this.get('ready', true);
return response;
});
},
// SSO in the form of 'domain:email:password'
sso: function(credentials) {
let url = this.appMeta.getUrl('public/authenticate');
this.clearSession();
if (is.empty(credentials.email) || is.empty(credentials.password)) {
return Ember.RSVP.reject("invalid");
}
var headers = {
'Authorization': 'Basic ' + credentials
};
return this.get('ajax').post(url, {
headers
}).then((response)=>{
this.setSession(response.token, models.UserModel.create(response.user));
this.get('ready', true);
return response;
});
},
// Goodbye
logout: function() {
this.clearSession();
},
// Session management
setSession: function(token, user) {
this.set('user', user);
this.set('authenticated', true);
this.storeSessionItem('token', token);
this.storeSessionItem('user', JSON.stringify(user));
let self = this;
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
// We only tack on auth header for Documize API calls
if (is.startWith(options.url, self.get('appMeta.url'))) {
jqXHR.setRequestHeader('Authorization', 'Bearer ' + token);
}
});
},
clearSession: function() {
this.set('user', null);
this.set('authenticated', false);
localStorage.clear();
},
storeSessionItem: function(key, data) {
localStorage[key] = data;
},
getSessionItem: function(key) {
return localStorage[key];
},
clearSessionItem: function(key) {
delete localStorage[key];
},
// Application boot process
boot() {
let self = this;
let dbhash = "";
if (is.not.null(document.head.querySelector("[property=dbhash]"))) {
dbhash = document.head.querySelector("[property=dbhash]").content;
}
if (dbhash.length > 0 && dbhash !== "{{.DBhash}}") {
self.get('appMeta').set('orgId', "response.orgId");
self.get('appMeta').setSafe('title', "Documize Setup");
self.get('appMeta').set('version', "response.version");
self.get('appMeta').setSafe('message', "response.message");
self.get('appMeta').set('allowAnonymousAccess', false);
self.set('ready', true);
return new Ember.RSVP.Promise(function(resolve) {
resolve();
});
}
if (this.get('ready')) {
return new Ember.RSVP.Promise(function(resolve) {
resolve();
});
}
let url = this.get('appMeta').getUrl("public/meta");
return this.get('ajax').request(url)
.then((response) => {
this.get('appMeta').set('orgId', response.orgId);
this.get('appMeta').setSafe('title', response.title);
this.get('appMeta').set('version', response.version);
this.get('appMeta').setSafe('message', response.message);
this.get('appMeta').set('allowAnonymousAccess', response.allowAnonymousAccess);
let token = this.getSessionItem('token');
if (is.not.undefined(token)) {
// We now validate current token
let tokenCheckUrl = this.get('appMeta').getUrl(`public/validate?token=${token}`);
return this.get('ajax').request(tokenCheckUrl, {
method: 'GET',
contentType: 'json'
}).then((user) => {
this.setSession(token, models.UserModel.create(user));
this.set('ready', true);
}).catch((reason) => {
if (netUtil.isAjaxAccessError(reason)) {
localStorage.clear();
window.location.href = "/auth/login";
}
});
}
});
}
}); });

View file

@ -17,8 +17,7 @@ export default Ember.Service.extend({
ajax: Ember.inject.service(), ajax: Ember.inject.service(),
importStockTemplate: function(folderId, templateId) { importStockTemplate: function(folderId, templateId) {
let url = `templates/${templateId}/folder/${folderId}?type=stock`;
let url = this.get('sessionService').appMeta.getUrl("templates/" + templateId + "/folder/" + folderId + "?type=stock");
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "POST" method: "POST"
@ -26,7 +25,7 @@ export default Ember.Service.extend({
}, },
importSavedTemplate: function(folderId, templateId) { importSavedTemplate: function(folderId, templateId) {
let url = this.get('sessionService').appMeta.getUrl("templates/" + templateId + "/folder/" + folderId + "?type=saved"); let url = `templates/${templateId}/folder/${folderId}?type=saved`;
return this.get('ajax').post(url).then((doc)=>{ return this.get('ajax').post(url).then((doc)=>{
let docModel = models.DocumentModel.create(doc); let docModel = models.DocumentModel.create(doc);
@ -35,9 +34,7 @@ export default Ember.Service.extend({
}, },
getSavedTemplates() { getSavedTemplates() {
let url = this.get('sessionService').appMeta.getUrl("templates"); return this.get('ajax').request(`templates`, {
return this.get('ajax').request(url, {
method: 'GET' method: 'GET'
}).then((response) => { }).then((response) => {
if (is.not.array(response)) { if (is.not.array(response)) {
@ -57,22 +54,19 @@ export default Ember.Service.extend({
}, },
getStockTemplates() { getStockTemplates() {
let url = this.get('sessionService').appMeta.getUrl("templates/stock"); return this.get('ajax').request(`templates/stock`, {
return this.get('ajax').request(url, {
method: 'GET' method: 'GET'
}); });
}, },
saveAsTemplate(documentId, name, excerpt) { saveAsTemplate(documentId, name, excerpt) {
let url = this.get('sessionService').appMeta.getUrl("templates");
let payload = { let payload = {
DocumentID: documentId, DocumentID: documentId,
Name: name, Name: name,
Excerpt: excerpt Excerpt: excerpt
}; };
return this.get('ajax').request(url, { return this.get('ajax').request(`templates`, {
method: 'POST', method: 'POST',
data: JSON.stringify(payload) data: JSON.stringify(payload)
}).then(() => { }).then(() => {

View file

@ -18,9 +18,8 @@ export default Ember.Service.extend({
// Adds a new user. // Adds a new user.
add(user) { add(user) {
let url = this.get('sessionService').appMeta.getUrl(`users`);
return this.get('ajax').request(url, { return this.get('ajax').request(`users`, {
type: 'POST', type: 'POST',
data: JSON.stringify(user), data: JSON.stringify(user),
contentType: 'json' contentType: 'json'
@ -31,7 +30,7 @@ export default Ember.Service.extend({
// Returns user model for specified user id. // Returns user model for specified user id.
getUser(userId) { getUser(userId) {
let url = this.get('sessionService').appMeta.getUrl(`users/${userId}`); let url = `users/${userId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
type: 'GET' type: 'GET'
@ -42,9 +41,7 @@ export default Ember.Service.extend({
// Returns all users for organization. // Returns all users for organization.
getAll() { getAll() {
let url = this.get('sessionService').appMeta.getUrl(`users`); return this.get('ajax').request(`users`).then((response) => {
return this.get('ajax').request(url).then((response) => {
return response.map(function(obj){ return response.map(function(obj){
return models.UserModel.create(obj); return models.UserModel.create(obj);
}); });
@ -53,7 +50,7 @@ export default Ember.Service.extend({
// Returns all users that can see folder. // Returns all users that can see folder.
getFolderUsers(folderId) { getFolderUsers(folderId) {
let url = this.get('sessionService').appMeta.getUrl(`users/folder/${folderId}`); let url = `users/folder/${folderId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: "GET" method: "GET"
@ -70,7 +67,7 @@ export default Ember.Service.extend({
// Updates an existing user record. // Updates an existing user record.
save(user) { save(user) {
let userId = user.get('id'); let userId = user.get('id');
let url = this.get('sessionService').appMeta.getUrl(`users/${userId}`); let url = `users/${userId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
type: 'PUT', type: 'PUT',
@ -81,7 +78,7 @@ export default Ember.Service.extend({
// updatePassword changes the password for the specified user. // updatePassword changes the password for the specified user.
updatePassword(userId, password) { updatePassword(userId, password) {
let url = this.get('sessionService').appMeta.getUrl(`users/${userId}/password`); let url = `users/${userId}/password`;
return this.get('ajax').post(url, { return this.get('ajax').post(url, {
data: password data: password
@ -90,7 +87,7 @@ export default Ember.Service.extend({
// Removes the specified user. // Removes the specified user.
remove(userId) { remove(userId) {
let url = this.get('sessionService').appMeta.getUrl(`users/${userId}`); let url = `users/${userId}`;
return this.get('ajax').request(url, { return this.get('ajax').request(url, {
method: 'DELETE' method: 'DELETE'
@ -99,7 +96,7 @@ export default Ember.Service.extend({
// Request password reset. // Request password reset.
forgotPassword(email) { forgotPassword(email) {
let url = this.get('sessionService').appMeta.getUrl('public/forgot'); let url = `public/forgot`;
if (is.empty(email)) { if (is.empty(email)) {
return Ember.RSVP.reject("invalid"); return Ember.RSVP.reject("invalid");
@ -118,7 +115,7 @@ export default Ember.Service.extend({
// Set new password. // Set new password.
resetPassword(token, password) { resetPassword(token, password) {
var url = this.get('sessionService').appMeta.getUrl('public/reset/' + token); var url = `public/reset/${token}`;
if (is.empty(token) || is.empty(password)) { if (is.empty(token) || is.empty(password)) {
return Ember.RSVP.reject("invalid"); return Ember.RSVP.reject("invalid");

View file

@ -15,7 +15,7 @@
{{#each attachments key="id" as |a index|}} {{#each attachments key="id" as |a index|}}
<li class="item"> <li class="item">
<img class="icon" src="assets/img/attachments/{{document/file-icon a.extension}}" /> <img class="icon" src="assets/img/attachments/{{document/file-icon a.extension}}" />
<a href="{{ session.appMeta.apiUrl }}api/public/attachments/{{ session.appMeta.orgId }}/{{ a.job }}/{{ a.fileId }}"> <a href="{{ appMeta.apiUrl }}api/public/attachments/{{ appMeta.orgId }}/{{ a.job }}/{{ a.fileId }}">
<span class="file">{{ a.filename }}</span> <span class="file">{{ a.filename }}</span>
</a> </a>
{{#if isEditor}} {{#if isEditor}}

View file

@ -6,13 +6,13 @@
</div> </div>
{{else}} {{else}}
{{#link-to 'application' class='title'}} {{#link-to 'application' class='title'}}
<div class="header-button" title=session.appMeta.title> <div class="header-button" title=appMeta.title>
<i class="material-icons">apps</i> <i class="material-icons">apps</i>
</div> </div>
{{/link-to}} {{/link-to}}
{{/if}} {{/if}}
{{#link-to 'application' class='title'}} {{#link-to 'application' class='title'}}
{{session.appMeta.title}} {{appMeta.title}}
{{/link-to}} {{/link-to}}
</div> </div>

View file

@ -29,6 +29,11 @@ module.exports = function(environment) {
"ember-cli-mirage": { "ember-cli-mirage": {
enabled: false enabled: false
}, },
'ember-simple-auth': {
authenticationRoute: 'auth.login',
routeAfterAuthentication: 'folders.folder',
routeIfAlreadyAuthenticated: 'folders.folder'
},
APP: { APP: {
// Allows to disable audit service in tests // Allows to disable audit service in tests
auditEnabled: true, auditEnabled: true,
@ -44,13 +49,14 @@ module.exports = function(environment) {
}; };
ENV.apiHost = "https://localhost:5001"; ENV.apiHost = "https://localhost:5001";
ENV.apiNamespace = "api";
} }
if (environment === 'test') { if (environment === 'test') {
ENV.APP.LOG_RESOLVER = false; ENV.APP.LOG_RESOLVER = false;
ENV.APP.LOG_ACTIVE_GENERATION = false; ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false; ENV.APP.LOG_VIEW_LOOKUPS = false;
// ENV.APP.LOG_TRANSITIONS = false; ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = false; // ENV.APP.LOG_TRANSITIONS_INTERNAL = false;
ENV.baseURL = '/'; ENV.baseURL = '/';

View file

@ -1,3 +1,5 @@
import Mirage from 'ember-cli-mirage';
export default function () { export default function () {
this.passthrough('https://widget.intercom.io/widget/%7Bapp_id%7D'); this.passthrough('https://widget.intercom.io/widget/%7Bapp_id%7D');
@ -5,6 +7,8 @@ export default function() {
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
this.logging = true;
this.get('/public/meta', function (schema) { this.get('/public/meta', function (schema) {
return schema.db.meta[0]; return schema.db.meta[0];
}); });
@ -121,7 +125,12 @@ export default function() {
return folder; return folder;
}); });
this.post('/public/authenticate', () => { this.post('/public/authenticate', (schema, request) => {
let authorization = request.requestHeaders.Authorization;
let expectedAuthorization = "Basic OmJyaXpkaWdpdGFsQGdtYWlsLmNvbTp6aW55YW5kbzEyMw==";
if (expectedAuthorization == authorization) {
console.log("SSO login success");
return { return {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkb21haW4iOiIiLCJleHAiOjE0NjQwMjM2NjcsImlzcyI6IkRvY3VtaXplIiwib3JnIjoiVnpNdXlFd18zV3FpYWZjRCIsInN1YiI6IndlYmFwcCIsInVzZXIiOiJWek11eUV3XzNXcWlhZmNFIn0.NXZ6bo8mtvdZF_b9HavbidVUJqhmBA1zr0fSAPvbah0", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkb21haW4iOiIiLCJleHAiOjE0NjQwMjM2NjcsImlzcyI6IkRvY3VtaXplIiwib3JnIjoiVnpNdXlFd18zV3FpYWZjRCIsInN1YiI6IndlYmFwcCIsInVzZXIiOiJWek11eUV3XzNXcWlhZmNFIn0.NXZ6bo8mtvdZF_b9HavbidVUJqhmBA1zr0fSAPvbah0",
"user": { "user": {
@ -150,6 +159,41 @@ export default function() {
}] }]
} }
}; };
}
if (expectedAuthorization != authorization) {
return new Mirage.Response(401, { 'Content-Type': 'application/json' }, { message: 'Bad Request' });
}
return {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkb21haW4iOiIiLCJleHAiOjE0NjQwMjM2NjcsImlzcyI6IkRvY3VtaXplIiwib3JnIjoiVnpNdXlFd18zV3FpYWZjRCIsInN1YiI6IndlYmFwcCIsInVzZXIiOiJWek11eUV3XzNXcWlhZmNFIn0.NXZ6bo8mtvdZF_b9HavbidVUJqhmBA1zr0fSAPvbah0",
"user": {
"id": "VzMuyEw_3WqiafcE",
"created": "2016-05-11T15:08:24Z",
"revised": "2016-05-11T15:08:24Z",
"firstname": "Lennex",
"lastname": "Zinyando",
"email": "brizdigital@gmail.com",
"initials": "LZ",
"active": true,
"editor": true,
"admin": true,
"accounts": [{
"id": "VzMuyEw_3WqiafcF",
"created": "2016-05-11T15:08:24Z",
"revised": "2016-05-11T15:08:24Z",
"admin": true,
"editor": true,
"userId": "VzMuyEw_3WqiafcE",
"orgId": "VzMuyEw_3WqiafcD",
"company": "EmberSherpa",
"title": "EmberSherpa",
"message": "This Documize instance contains all our team documentation",
"domain": ""
}]
}
};
}); });
this.get('/users/VzMuyEw_3WqiafcE/permissions', (schema) => { this.get('/users/VzMuyEw_3WqiafcE/permissions', (schema) => {
@ -157,19 +201,16 @@ export default function() {
}); });
this.get('/folders/VzMuyEw_3WqiafcG/permissions', () => { this.get('/folders/VzMuyEw_3WqiafcG/permissions', () => {
return [ return [{
{
"folderId": "VzMuyEw_3WqiafcG", "folderId": "VzMuyEw_3WqiafcG",
"userId": "VzMuyEw_3WqiafcE", "userId": "VzMuyEw_3WqiafcE",
"canView": true, "canView": true,
"canEdit": true "canEdit": true
} }];
];
}); });
this.put('/folders/VzMygEw_3WrtFzto/permissions', () => { this.put('/folders/VzMygEw_3WrtFzto/permissions', () => {
return [ return [{
{
"orgId": "VzMuyEw_3WqiafcD", "orgId": "VzMuyEw_3WqiafcD",
"folderId": "VzMygEw_3WrtFzto", "folderId": "VzMygEw_3WrtFzto",
"userId": "", "userId": "",
@ -187,19 +228,16 @@ export default function() {
"userId": "VzMuyEw_3WqiafcE", "userId": "VzMuyEw_3WqiafcE",
"canEdit": true, "canEdit": true,
"canView": true "canView": true
} }];
];
}); });
this.get('/folders/VzMygEw_3WrtFzto/permissions', () => { this.get('/folders/VzMygEw_3WrtFzto/permissions', () => {
return [ return [{
{
"folderId": "VzMygEw_3WrtFzto", "folderId": "VzMygEw_3WrtFzto",
"userId": "VzMuyEw_3WqiafcE", "userId": "VzMuyEw_3WqiafcE",
"canView": true, "canView": true,
"canEdit": true "canEdit": true
} }];
];
}); });
this.put('/folders/:id', (schema, request) => { this.put('/folders/:id', (schema, request) => {
@ -338,8 +376,8 @@ export default function() {
"title": "EmberSherpa", "title": "EmberSherpa",
"message": "This Documize instance contains all our team documentation", "message": "This Documize instance contains all our team documentation",
"domain": "" "domain": ""
} }]
]}; };
}); });
this.get('/users/VzMuyEw_3WqiafcE', () => { this.get('/users/VzMuyEw_3WqiafcE', () => {
@ -367,8 +405,8 @@ export default function() {
"title": "EmberSherpa", "title": "EmberSherpa",
"message": "This Documize instance contains all our team documentation", "message": "This Documize instance contains all our team documentation",
"domain": "" "domain": ""
} }]
]}; };
}); });
this.put('/users/VzMuyEw_3WqiafcE', (schema, request) => { this.put('/users/VzMuyEw_3WqiafcE', (schema, request) => {
@ -399,23 +437,12 @@ export default function() {
"title": "EmberSherpa", "title": "EmberSherpa",
"message": "This Documize instance contains all our team documentation", "message": "This Documize instance contains all our team documentation",
"domain": "" "domain": ""
} }]
]}; };
}); });
this.post('/folders/VzMuyEw_3WqiafcG/invitation', () => { this.post('/folders/VzMuyEw_3WqiafcG/invitation', () => {
return {}; return {};
}); });
/**
very helpful for debugging
*/
this.handledRequest = function(verb, path) {
console.log(`👊${verb} ${path}`);
};
this.unhandledRequest = function(verb, path) {
console.log(`🔥${verb} ${path}`);
};
} }

View file

@ -39,6 +39,7 @@
"ember-export-application-global": "^1.0.5", "ember-export-application-global": "^1.0.5",
"ember-load-initializers": "^0.5.1", "ember-load-initializers": "^0.5.1",
"ember-resolver": "^2.0.3", "ember-resolver": "^2.0.3",
"ember-simple-auth": "git+https://github.com/documize/ember-simple-auth.git#21e638f9e33267d8944835002ee96884d34d568a",
"loader.js": "^4.0.1" "loader.js": "^4.0.1"
}, },
"ember-addon": { "ember-addon": {

View file

@ -31,7 +31,8 @@
"waitToAppear", "waitToAppear",
"waitToAppear", "waitToAppear",
"stubUserNotification", "stubUserNotification",
"is" "is",
"authenticateUser"
], ],
"node": false, "node": false,
"browser": false, "browser": false,

View file

@ -3,7 +3,6 @@ import moduleForAcceptance from 'documize/tests/helpers/module-for-acceptance';
moduleForAcceptance('Acceptance | Anon access disabled'); moduleForAcceptance('Acceptance | Anon access disabled');
test('visiting / when not authenticated and with { allowAnonymousAccess: false } takes user to login', function (assert) { test('visiting / when not authenticated and with { allowAnonymousAccess: false } takes user to login', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);

View file

@ -7,7 +7,6 @@ test('visiting / when not authenticated and with { allowAnonymousAccess: true }
server.create('meta', { allowAnonymousAccess: true }); server.create('meta', { allowAnonymousAccess: true });
server.createList('folder', 2); server.createList('folder', 2);
visit('/'); visit('/');
// return pauseTest();
andThen(function () { andThen(function () {
assert.equal(find('.login').length, 1, 'Login button is displayed'); assert.equal(find('.login').length, 1, 'Login button is displayed');

View file

@ -13,7 +13,7 @@ test('visiting /auth/login and logging in', function(assert) {
click('button'); click('button');
andThen(function () { andThen(function () {
assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project', 'Login successfull'); assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project', 'Login successful');
}); });
}); });
@ -25,6 +25,28 @@ test('logging out a user', function(assert) {
visit('/auth/logout'); visit('/auth/logout');
andThen(function () { andThen(function () {
assert.equal(currentURL(), '/auth/login', 'Login successfull'); assert.equal(currentURL(), '/auth/login', 'Logging out successful');
});
});
test('successful sso login authenticates redirects to dashboard', function (assert) {
server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2);
visit('/auth/sso/OmJyaXpkaWdpdGFsQGdtYWlsLmNvbTp6aW55YW5kbzEyMw==');
andThen(function () {
assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project', 'SSO login successful');
});
});
test('sso login with bad token should redirect to login', function (assert) {
server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2);
visit('/auth/sso/randomToken1234567890');
andThen(function () {
assert.equal(currentURL(), '/auth/login', 'SSO login unsuccessful');
}); });
}); });

View file

@ -1,13 +1,13 @@
import { test } from 'qunit'; import { test, skip } from 'qunit';
import moduleForAcceptance from 'documize/tests/helpers/module-for-acceptance'; import moduleForAcceptance from 'documize/tests/helpers/module-for-acceptance';
moduleForAcceptance('Acceptance | Documents space'); moduleForAcceptance('Acceptance | Documents space');
test('Adding a new folder space', function(assert) { skip('Adding a new folder space', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMuyEw_3WqiafcG/my-project'); visit('/s/VzMuyEw_3WqiafcG/my-project');
andThen(function () { andThen(function () {
@ -27,36 +27,35 @@ test('Adding a new folder space', function(assert) {
}); });
}); });
// test('Adding a document to a space', function(assert) { skip('Adding a document to a space', function (assert) {
// server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
// server.createList('folder', 2); server.createList('folder', 2);
// server.createList('permission', 4); server.createList('permission', 4);
// userLogin(); authenticateUser();
// visit('/s/VzMuyEw_3WqiafcG/my-project'); visit('/s/VzMuyEw_3WqiafcG/my-project');
//
// andThen(function() { andThen(function () {
//
// let numberOfDocuments = find('.documents-list li').length; let numberOfDocuments = find('.documents-list li').length;
// assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project'); assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project');
// assert.equal(numberOfDocuments, 2, '2 documents listed'); assert.equal(numberOfDocuments, 2, '2 documents listed');
// }); });
//
// click('#start-document-button'); click('#start-document-button');
// click('.actions div:contains(Add)', 'body'); click('.actions div:contains(Add)', 'body');
//
// andThen(function() { andThen(function () {
// let numberOfDocuments = find('.documents-list li').length; let numberOfDocuments = find('.documents-list li').length;
// assert.equal(numberOfDocuments, 3, '3 documents listed'); assert.equal(numberOfDocuments, 3, '3 documents listed');
// assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project'); assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project');
// // return pauseTest(); });
// }); });
// });
test('visiting space settings page', function (assert) { test('visiting space settings page', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMuyEw_3WqiafcG/my-project'); visit('/s/VzMuyEw_3WqiafcG/my-project');
click('#folder-settings-button'); click('#folder-settings-button');
@ -72,14 +71,16 @@ test('changing space name', function(assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMuyEw_3WqiafcG/my-project/settings'); visit('/s/VzMuyEw_3WqiafcG/my-project');
click('#folder-settings-button');
fillIn('#folderName', 'Test Space'); fillIn('#folderName', 'Test Space');
click('.button-blue'); click('.button-blue');
andThen(function () { andThen(function () {
let spaceName = find('.breadcrumb-menu .selected').text().trim(); let spaceName = find('.info .title').text().trim();
checkForCommonAsserts(); checkForCommonAsserts();
assert.equal(spaceName, 'Test Space', 'Space name has been changed'); assert.equal(spaceName, 'Test Space', 'Space name has been changed');
assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project/settings'); assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project/settings');
@ -90,8 +91,10 @@ test('sharing a space', function(assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMuyEw_3WqiafcG/my-project/settings'); visit('/s/VzMuyEw_3WqiafcG/my-project');
click('#folder-settings-button');
click(('.sidebar-menu .options li:contains(Share)')); click(('.sidebar-menu .options li:contains(Share)'));
fillIn('#inviteEmail', 'share-test@gmail.com'); fillIn('#inviteEmail', 'share-test@gmail.com');
@ -103,32 +106,34 @@ test('sharing a space', function(assert) {
}); });
}); });
// Test will pass after moving to factories // Test will pass after moving to factories
test('changing space permissions', function (assert) { test('changing space permissions', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMygEw_3WrtFzto/test');
andThen(function () { andThen(function () {
let numberOfPublicFolders = find('.folders-list div:first .list a').length; let numberOfPublicFolders = find('.sidebar-menu .folders-list .section .list:first a').length;
assert.equal(numberOfPublicFolders, 1, '1 folder listed as public'); assert.equal(numberOfPublicFolders, 1, '1 folder listed as public');
assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project'); assert.equal(currentURL(), '/s/VzMygEw_3WrtFzto/test');
}); });
visit('/s/VzMygEw_3WrtFzto/test/settings'); click('#folder-settings-button');
click(('.sidebar-menu .options li:contains(Permissions)'));
click('.sidebar-menu .options li:contains(Permissions)');
click('tr:contains(Everyone) #canView-'); click('tr:contains(Everyone) #canView-');
click('tr:contains(Everyone) #canEdit-'); click('tr:contains(Everyone) #canEdit-');
click('.button-blue'); click('.button-blue');
visit('/s/VzMuyEw_3WqiafcG/my-project'); visit('/s/VzMygEw_3WrtFzto/test');
andThen(function () { andThen(function () {
let numberOfPublicFolders = find('.folders-list div:first .list a').length; let numberOfPublicFolders = find('.folders-list div:contains(EVERYONE) .list a').length;
assert.equal(numberOfPublicFolders, 2, '2 folder listed as public'); assert.equal(numberOfPublicFolders, 2, '2 folder listed as public');
assert.equal(currentURL(), '/s/VzMuyEw_3WqiafcG/my-project'); assert.equal(currentURL(), '/s/VzMygEw_3WrtFzto/test');
}); });
}); });
@ -136,8 +141,10 @@ test('deleting a space', function(assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
server.createList('folder', 2); server.createList('folder', 2);
server.createList('permission', 4); server.createList('permission', 4);
userLogin(); authenticateUser();
visit('/s/VzMuyEw_3WqiafcG/my-project/settings'); visit('/s/VzMuyEw_3WqiafcG/my-project');
click('#folder-settings-button');
click('.sidebar-menu .options li:contains(Delete)'); click('.sidebar-menu .options li:contains(Delete)');
@ -147,37 +154,37 @@ test('deleting a space', function(assert) {
}); });
}); });
// test('deleting a document', function(assert) { skip('deleting a document', function (assert) {
// server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
// server.createList('folder', 2); server.createList('folder', 2);
// server.createList('permission', 4); server.createList('permission', 4);
// userLogin(); authenticateUser();
// visit('/s/VzMuyEw_3WqiafcG/my-project'); visit('/s/VzMuyEw_3WqiafcG/my-project');
//
// andThen(function() { andThen(function () {
// let deleteButton = find('#delete-documents-button'); let deleteButton = find('#delete-documents-button');
// let numberOfDocuments = find('.documents-list li'); let numberOfDocuments = find('.documents-list li');
// assert.equal(numberOfDocuments.length, 2, '2 documents are displayed'); assert.equal(numberOfDocuments.length, 2, '2 documents are displayed');
// assert.equal(deleteButton.length, 0, 'Delete button not displayed'); assert.equal(deleteButton.length, 0, 'Delete button not displayed');
// }); });
//
// click('.documents-list li:first .checkbox'); click('.documents-list li:first .checkbox');
//
// andThen(function() { andThen(function () {
// let deleteButton = find('#delete-documents-button'); let deleteButton = find('#delete-documents-button');
// assert.equal(deleteButton.length, 1, 'Delete button displayed after selecting document'); assert.equal(deleteButton.length, 1, 'Delete button displayed after selecting document');
// }); });
//
// click('#delete-documents-button'); click('#delete-documents-button');
//
// waitToAppear('.drop-content'); waitToAppear('.drop-content');
// click('.actions div:contains(Delete)', 'body'); click('.actions div:contains(Delete)', 'body');
//
// andThen(function() { andThen(function () {
// let numberOfDocuments = find('.documents-list li'); let numberOfDocuments = find('.documents-list li');
// assert.equal(numberOfDocuments.length, 1, '1 documents is displayed'); assert.equal(numberOfDocuments.length, 1, '1 documents is displayed');
// }); });
// }); });
function checkForCommonAsserts() { function checkForCommonAsserts() {
findWithAssert('.sidebar-menu'); findWithAssert('.sidebar-menu');

View file

@ -5,7 +5,7 @@ moduleForAcceptance('Acceptance | user profile');
test('visiting /profile', function (assert) { test('visiting /profile', function (assert) {
server.createList('folder', 2); server.createList('folder', 2);
userLogin(); authenticateUser();
visit('/profile'); visit('/profile');
andThen(function () { andThen(function () {
@ -18,12 +18,12 @@ test('visiting /profile', function(assert) {
test('changing user details and email ', function (assert) { test('changing user details and email ', function (assert) {
server.createList('folder', 2); server.createList('folder', 2);
userLogin(); authenticateUser();
visit('/profile'); visit('/profile');
andThen(function () { andThen(function () {
assert.equal(currentURL(), '/profile'); assert.equal(currentURL(), '/profile');
assert.equal(find('.name').text().trim(), 'Lennex Zinyando', 'Profile name displayed'); assert.equal(find('.content .name').text().trim(), 'Lennex Zinyando', 'Profile name displayed');
assert.equal(find('#firstname').val(), 'Lennex', 'Firstaname input displays correct value'); assert.equal(find('#firstname').val(), 'Lennex', 'Firstaname input displays correct value');
assert.equal(find('#lastname').val(), 'Zinyando', 'Lastname input displays correct value'); assert.equal(find('#lastname').val(), 'Zinyando', 'Lastname input displays correct value');
assert.equal(find('#email').val(), 'brizdigital@gmail.com', 'Email input displays correct value'); assert.equal(find('#email').val(), 'brizdigital@gmail.com', 'Email input displays correct value');

View file

@ -5,7 +5,7 @@ moduleForAcceptance('Acceptance | User Settings');
test('visiting /settings/general', function (assert) { test('visiting /settings/general', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
userLogin(); authenticateUser();
visit('/settings/general'); visit('/settings/general');
andThen(function () { andThen(function () {
@ -18,7 +18,7 @@ test('visiting /settings/general', function(assert) {
test('changing the Website title and description', function (assert) { test('changing the Website title and description', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
userLogin(); authenticateUser();
visit('/settings/general'); visit('/settings/general');
andThen(function () { andThen(function () {
@ -39,7 +39,7 @@ test('changing the Website title and description', function(assert) {
test('visiting /settings/folders', function (assert) { test('visiting /settings/folders', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
userLogin(); authenticateUser();
visit('/settings/folders'); visit('/settings/folders');
andThen(function () { andThen(function () {
@ -50,7 +50,7 @@ test('visiting /settings/folders', function(assert) {
test('visiting /settings/users', function (assert) { test('visiting /settings/users', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
userLogin(); authenticateUser();
visit('/settings/users'); visit('/settings/users');
andThen(function () { andThen(function () {
@ -64,7 +64,7 @@ test('visiting /settings/users', function(assert) {
test('add a new user', function (assert) { test('add a new user', function (assert) {
server.create('meta', { allowAnonymousAccess: false }); server.create('meta', { allowAnonymousAccess: false });
userLogin(); authenticateUser();
visit('/settings/users'); visit('/settings/users');
andThen(function () { andThen(function () {
@ -95,6 +95,5 @@ function checkForCommonAsserts() {
findWithAssert('.sidebar-menu'); findWithAssert('.sidebar-menu');
findWithAssert('#user-button'); findWithAssert('#user-button');
findWithAssert('#accounts-button'); findWithAssert('#accounts-button');
findWithAssert('a:contains(Dashboard)'); findWithAssert('.info .title');
findWithAssert('a:contains(Settings)');
} }

View file

@ -0,0 +1,38 @@
import Ember from 'ember';
import { authenticateSession } from 'documize/tests/helpers/ember-simple-auth';
const {
merge
} = Ember;
export default Ember.Test.registerAsyncHelper('authenticateUser', function(app, attrs = {}) {
authenticateSession(app, merge({
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkb21haW4iOiIiLCJleHAiOjE0NjQwMjM2NjcsImlzcyI6IkRvY3VtaXplIiwib3JnIjoiVnpNdXlFd18zV3FpYWZjRCIsInN1YiI6IndlYmFwcCIsInVzZXIiOiJWek11eUV3XzNXcWlhZmNFIn0.NXZ6bo8mtvdZF_b9HavbidVUJqhmBA1zr0fSAPvbah0",
user: {
"id": "VzMuyEw_3WqiafcE",
"created": "2016-05-11T15:08:24Z",
"revised": "2016-05-11T15:08:24Z",
"firstname": "Lennex",
"lastname": "Zinyando",
"email": "brizdigital@gmail.com",
"initials": "LZ",
"active": true,
"editor": true,
"admin": true,
"accounts": [{
"id": "VzMuyEw_3WqiafcF",
"created": "2016-05-11T15:08:24Z",
"revised": "2016-05-11T15:08:24Z",
"admin": true,
"editor": true,
"userId": "VzMuyEw_3WqiafcE",
"orgId": "VzMuyEw_3WqiafcD",
"company": "EmberSherpa",
"title": "EmberSherpa",
"message": "This Documize instance contains all our team documentation",
"domain": ""
}]
}
}, attrs)
);
});

View file

@ -7,7 +7,6 @@ export default function(name, options = {}) {
beforeEach() { beforeEach() {
this.application = startApp(); this.application = startApp();
stubAudit(this); stubAudit(this);
stubSession(this);
stubUserNotification(this); stubUserNotification(this);
if (options.beforeEach) { if (options.beforeEach) {

View file

@ -1,12 +1,12 @@
import Ember from 'ember'; import Ember from 'ember';
import Application from '../../app'; import Application from '../../app';
import config from '../../config/environment'; import config from '../../config/environment';
import './stub-session';
import './stub-audit'; import './stub-audit';
import './user-login'; import './user-login';
import './wait-to-appear'; import './wait-to-appear';
import './wait-to-disappear'; import './wait-to-disappear';
import './stub-user-notification'; import './stub-user-notification';
import './authenticate-user';
export default function startApp(attrs) { export default function startApp(attrs) {
let application; let application;

View file

@ -1,200 +0,0 @@
import Ember from 'ember';
import models from 'documize/utils/model';
import encodingUtil from 'documize/utils/encoding';
import netUtil from 'documize/utils/net';
const Session = Ember.Service.extend({
ready: false,
appMeta: null,
isMac: false,
isMobile: false,
previousTransition: null,
user: null,
authenticated: false,
folderPermissions: null,
currentFolder: null,
ajax: Ember.inject.service(),
isAdmin: function() {
if (this.authenticated && is.not.null(this.user) && this.user.id !== "") {
return this.user.admin;
}
return false;
}.property('user'),
isEditor: function() {
if (this.authenticated && is.not.null(this.user) && this.user.id !== "") {
return this.user.editor || this.user.admin;
}
return false;
}.property('user'),
// Boot up
init: function() {
this.set('user', models.UserModel.create());
this.appMeta = models.AppMeta.create();
this.set('isMac', is.mac());
this.set('isMobile', is.mobile());
},
login: function(credentials) {
let url = this.appMeta.getUrl('public/authenticate');
let domain = netUtil.getSubdomain();
this.clearSession();
if (is.empty(credentials.email) || is.empty(credentials.password)) {
return Ember.RSVP.reject("invalid");
}
var encoded = encodingUtil.Base64.encode(domain + ":" + credentials.email + ":" + credentials.password);
var headers = {
'Authorization': 'Basic ' + encoded
};
return this.get('ajax').post(url, {
headers
}).then((response)=>{
this.setSession(response.token, models.UserModel.create(response.user));
this.get('ready', true);
return response;
});
},
sso: function(credentials) {
let url = this.appMeta.getUrl('public/authenticate');
this.clearSession();
if (is.empty(credentials.email) || is.empty(credentials.password)) {
return Ember.RSVP.reject("invalid");
}
var headers = {
'Authorization': 'Basic ' + credentials
};
return this.get('ajax').post(url, {
headers
}).then((response)=>{
this.setSession(response.token, models.UserModel.create(response.user));
this.get('ready', true);
return response;
});
},
// Goodbye
logout: function() {
this.clearSession();
},
// Session management
setSession: function(token, user) {
this.set('user', user);
this.set('authenticated', true);
this.storeSessionItem('token', token);
this.storeSessionItem('user', JSON.stringify(user));
let self = this;
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
// We only tack on auth header for Documize API calls
if (is.startWith(options.url, self.get('appMeta.url'))) {
jqXHR.setRequestHeader('Authorization', 'Bearer ' + token);
}
});
},
clearSession: function() {
this.set('user', null);
this.set('authenticated', false);
// localStorage.clear();
},
storeSessionItem: function() {
// localStorage[key] = data;
// console.log(data);
},
getSessionItem: function() {
// return localStorage[key];
// console.log(data);
},
clearSessionItem: function() {
// delete localStorage[key];
},
boot() {
let self = this;
let dbhash = "";
if (is.not.null(document.head.querySelector("[property=dbhash]"))) {
dbhash = document.head.querySelector("[property=dbhash]").content;
}
if (dbhash.length > 0 && dbhash !== "{{.DBhash}}") {
self.get('appMeta').set('orgId', "response.orgId");
self.get('appMeta').setSafe('title', "Documize Setup");
self.get('appMeta').set('version', "response.version");
self.get('appMeta').setSafe('message', "response.message");
self.get('appMeta').set('allowAnonymousAccess', false);
self.set('ready', true);
return new Ember.RSVP.Promise(function(resolve) {
resolve();
});
}
if (this.get('ready')) {
return new Ember.RSVP.Promise(function(resolve) {
resolve();
});
}
// var blockedPopupTest = window.open("http://maintenance.documize.com", "directories=no,height=1,width=1,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=0,location=no");
//
// if (!blockedPopupTest) {
// this.set('popupBlocked', true);
// } else {
// blockedPopupTest.close();
// this.set('popupBlocked', false);
// }
let url = this.get('appMeta').getUrl("public/meta");
return this.get('ajax').request(url)
.then((response) => {
this.get('appMeta').set('orgId', response.orgId);
this.get('appMeta').setSafe('title', response.title);
this.get('appMeta').set('version', response.version);
this.get('appMeta').setSafe('message', response.message);
this.get('appMeta').set('allowAnonymousAccess', response.allowAnonymousAccess);
let token = this.getSessionItem('token');
if (is.not.undefined(token)) {
// We now validate current token
let tokenCheckUrl = this.get('appMeta').getUrl(`public/validate?token=${token}`);
return this.get('ajax').request(tokenCheckUrl, {
method: 'GET',
contentType: 'json'
}).then((user) => {
this.setSession(token, models.UserModel.create(user));
this.set('ready', true);
}).catch((reason) => {
if (reason.status === 401 || reason.status === 403) {
// localStorage.clear();
window.location.href = "/auth/login";
}
});
}
});
}
});
export default Ember.Test.registerAsyncHelper('stubSession', function(app, test, attrs={}) {
test.register('service:session', Session.extend(attrs));
});

View file

@ -0,0 +1,12 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('service:local-storage', 'Unit | Service | local storage', {
// Specify the other units that are required for this test.
// needs: ['service:foo']
});
// Replace this with your real tests.
test('it exists', function(assert) {
let service = this.subject();
assert.ok(service);
});