mirror of
https://github.com/documize/community.git
synced 2025-07-19 05:09:42 +02:00
Provide in-app What's New & new release notifications
This commit is contained in:
parent
97cc5374f0
commit
eaf46f06c1
25 changed files with 1166 additions and 772 deletions
|
@ -24,4 +24,7 @@ INSERT INTO search (orgid, documentid, itemid, itemtype, content)
|
|||
SELECT orgid, documentid, refid as itemid, "page" as itemtype, title as content
|
||||
FROM page WHERE status=0
|
||||
|
||||
-- whats new support
|
||||
ALTER TABLE user ADD COLUMN `lastversion` CHAR(16) NOT NULL DEFAULT '' AFTER `active`;
|
||||
|
||||
-- deprecations
|
||||
|
|
|
@ -39,6 +39,7 @@ type RequestContext struct {
|
|||
Expires time.Time
|
||||
Fullname string
|
||||
Transaction *sqlx.Tx
|
||||
AppVersion string
|
||||
}
|
||||
|
||||
//GetAppURL returns full HTTP url for the app
|
||||
|
|
|
@ -100,6 +100,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
|||
requestedPassword := secrets.GenerateRandomPassword()
|
||||
userModel.Salt = secrets.GenerateSalt()
|
||||
userModel.Password = secrets.GeneratePassword(requestedPassword, userModel.Salt)
|
||||
userModel.LastVersion = ctx.AppVersion
|
||||
|
||||
// only create account if not dupe
|
||||
addUser := true
|
||||
|
|
|
@ -35,8 +35,8 @@ func (s Scope) Add(ctx domain.RequestContext, u user.User) (err error) {
|
|||
u.Created = time.Now().UTC()
|
||||
u.Revised = time.Now().UTC()
|
||||
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO user (refid, firstname, lastname, email, initials, password, salt, reset, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
u.RefID, u.Firstname, u.Lastname, strings.ToLower(u.Email), u.Initials, u.Password, u.Salt, "", u.Created, u.Revised)
|
||||
_, err = ctx.Transaction.Exec("INSERT INTO user (refid, firstname, lastname, email, initials, password, salt, reset, lastversion, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
u.RefID, u.Firstname, u.Lastname, strings.ToLower(u.Email), u.Initials, u.Password, u.Salt, "", u.LastVersion, u.Created, u.Revised)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "execute user insert")
|
||||
|
@ -47,7 +47,7 @@ func (s Scope) Add(ctx domain.RequestContext, u user.User) (err error) {
|
|||
|
||||
// Get returns the user record for the given id.
|
||||
func (s Scope) Get(ctx domain.RequestContext, id string) (u user.User, err error) {
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, created, revised FROM user WHERE refid=?", id)
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, lastversion, created, revised FROM user WHERE refid=?", id)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("unable to execute select for user %s", id))
|
||||
|
@ -60,7 +60,7 @@ func (s Scope) Get(ctx domain.RequestContext, id string) (u user.User, err error
|
|||
func (s Scope) GetByDomain(ctx domain.RequestContext, domain, email string) (u user.User, err error) {
|
||||
email = strings.TrimSpace(strings.ToLower(email))
|
||||
|
||||
err = s.Runtime.Db.Get(&u, "SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.global, u.password, u.salt, u.reset, u.created, u.revised FROM user u, account a, organization o WHERE TRIM(LOWER(u.email))=? AND u.refid=a.userid AND a.orgid=o.refid AND TRIM(LOWER(o.domain))=?",
|
||||
err = s.Runtime.Db.Get(&u, "SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.global, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised FROM user u, account a, organization o WHERE TRIM(LOWER(u.email))=? AND u.refid=a.userid AND a.orgid=o.refid AND TRIM(LOWER(o.domain))=?",
|
||||
email, domain)
|
||||
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
|
@ -74,7 +74,7 @@ func (s Scope) GetByDomain(ctx domain.RequestContext, domain, email string) (u u
|
|||
func (s Scope) GetByEmail(ctx domain.RequestContext, email string) (u user.User, err error) {
|
||||
email = strings.TrimSpace(strings.ToLower(email))
|
||||
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, created, revised FROM user WHERE TRIM(LOWER(email))=?", email)
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, lastversion, created, revised FROM user WHERE TRIM(LOWER(email))=?", email)
|
||||
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
err = errors.Wrap(err, fmt.Sprintf("execute select user by email %s", email))
|
||||
|
@ -85,7 +85,7 @@ func (s Scope) GetByEmail(ctx domain.RequestContext, email string) (u user.User,
|
|||
|
||||
// GetByToken returns a user record given a reset token value.
|
||||
func (s Scope) GetByToken(ctx domain.RequestContext, token string) (u user.User, err error) {
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, created, revised FROM user WHERE reset=?", token)
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, lastversion, created, revised FROM user WHERE reset=?", token)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("execute user select by token %s", token))
|
||||
|
@ -98,7 +98,7 @@ func (s Scope) GetByToken(ctx domain.RequestContext, token string) (u user.User,
|
|||
// This occurs when we you share a folder with a new user and they have to complete
|
||||
// the onboarding process.
|
||||
func (s Scope) GetBySerial(ctx domain.RequestContext, serial string) (u user.User, err error) {
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, created, revised FROM user WHERE salt=?", serial)
|
||||
err = s.Runtime.Db.Get(&u, "SELECT id, refid, firstname, lastname, email, initials, global, password, salt, reset, lastversion, created, revised FROM user WHERE salt=?", serial)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("execute user select by serial %s", serial))
|
||||
|
@ -111,7 +111,7 @@ func (s Scope) GetBySerial(ctx domain.RequestContext, serial string) (u user.Use
|
|||
// identified in the Persister.
|
||||
func (s Scope) GetActiveUsersForOrganization(ctx domain.RequestContext) (u []user.User, err error) {
|
||||
err = s.Runtime.Db.Select(&u,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised,
|
||||
u.global, a.active, a.editor, a.admin, a.users as viewusers
|
||||
FROM user u, account a
|
||||
WHERE u.refid=a.userid AND a.orgid=? AND a.active=1
|
||||
|
@ -139,7 +139,7 @@ func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string)
|
|||
}
|
||||
|
||||
err = s.Runtime.Db.Select(&u,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised,
|
||||
u.global, a.active, a.editor, a.admin, a.users as viewusers
|
||||
FROM user u, account a
|
||||
WHERE u.refid=a.userid AND a.orgid=? `+likeQuery+
|
||||
|
@ -160,7 +160,7 @@ func (s Scope) GetUsersForOrganization(ctx domain.RequestContext, filter string)
|
|||
// GetSpaceUsers returns a slice containing all user records for given space.
|
||||
func (s Scope) GetSpaceUsers(ctx domain.RequestContext, spaceID string) (u []user.User, err error) {
|
||||
err = s.Runtime.Db.Select(&u, `
|
||||
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised, u.global,
|
||||
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.lastversion, u.revised, u.global,
|
||||
a.active, a.users AS viewusers, a.editor, a.admin
|
||||
FROM user u, account a
|
||||
WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN (
|
||||
|
@ -189,12 +189,12 @@ func (s Scope) GetUsersForSpaces(ctx domain.RequestContext, spaces []string) (u
|
|||
}
|
||||
|
||||
query, args, err := sqlx.In(`
|
||||
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised, u.global,
|
||||
SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised, u.global,
|
||||
a.active, a.users AS viewusers, a.editor, a.admin
|
||||
FROM user u, account a
|
||||
WHERE a.orgid=? AND u.refid = a.userid AND a.active=1 AND u.refid IN (
|
||||
SELECT whoid from permission WHERE orgid=? AND who='user' AND scope='object' AND location='space' AND refid IN(?) UNION ALL
|
||||
SELECT r.userid from rolemember r LEFT JOIN permission p ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.scope='object' AND p.location='space' AND p.refid IN(?)
|
||||
SELECT r.userid from rolemember r LEFT JOIN permission p ON p.whoid=r.roleid WHERE p.orgid=? AND p.who='role' AND p.scope='object' AND p.location='space' AND p.refid IN(?)
|
||||
)
|
||||
ORDER BY u.firstname, u.lastname
|
||||
`, ctx.OrgID, ctx.OrgID, spaces, ctx.OrgID, spaces)
|
||||
|
@ -219,7 +219,7 @@ func (s Scope) UpdateUser(ctx domain.RequestContext, u user.User) (err error) {
|
|||
u.Email = strings.ToLower(u.Email)
|
||||
|
||||
_, err = ctx.Transaction.NamedExec(
|
||||
"UPDATE user SET firstname=:firstname, lastname=:lastname, email=:email, revised=:revised, initials=:initials WHERE refid=:refid", &u)
|
||||
"UPDATE user SET firstname=:firstname, lastname=:lastname, email=:email, revised=:revised, initials=:initials, lastversion=:lastversion WHERE refid=:refid", &u)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("execute user update %s", u.RefID))
|
||||
|
@ -289,7 +289,7 @@ func (s Scope) MatchUsers(ctx domain.RequestContext, text string, maxMatches int
|
|||
}
|
||||
|
||||
err = s.Runtime.Db.Select(&u,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.created, u.revised,
|
||||
`SELECT u.id, u.refid, u.firstname, u.lastname, u.email, u.initials, u.password, u.salt, u.reset, u.lastversion, u.created, u.revised,
|
||||
u.global, a.active, a.editor, a.admin, a.users as viewusers
|
||||
FROM user u, account a
|
||||
WHERE a.orgid=? AND u.refid=a.userid AND a.active=1 `+likeQuery+
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -9,11 +9,30 @@
|
|||
//
|
||||
// https://documize.com
|
||||
|
||||
import $ from 'jquery';
|
||||
import { empty } from '@ember/object/computed';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
appMeta: service(),
|
||||
LicenseError: empty('model.license'),
|
||||
changelog: '',
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
let self = this;
|
||||
let cacheBuster = + new Date();
|
||||
$.ajax({
|
||||
url: `https://storage.googleapis.com/documize/downloads/updates/summary.html?cb=${cacheBuster}`,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
success: function (response) {
|
||||
self.set('changelog', response);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
saveLicense() {
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
//
|
||||
// https://documize.com
|
||||
|
||||
import Component from '@ember/component';
|
||||
import $ from 'jquery';
|
||||
import { notEmpty } from '@ember/object/computed';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { inject as service } from '@ember/service'
|
||||
import ModalMixin from '../../mixins/modal';
|
||||
import constants from '../../utils/constants';
|
||||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
export default Component.extend(ModalMixin, {
|
||||
folderService: service('folder'),
|
||||
appMeta: service(),
|
||||
session: service(),
|
||||
|
@ -24,6 +26,8 @@ export default Component.extend({
|
|||
hasPins: notEmpty('pins'),
|
||||
hasSpacePins: notEmpty('spacePins'),
|
||||
hasDocumentPins: notEmpty('documentPins'),
|
||||
hasWhatsNew: false,
|
||||
newsContent: '',
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
|
@ -34,6 +38,23 @@ export default Component.extend({
|
|||
config = JSON.parse(config);
|
||||
this.set('enableLogout', !config.disableLogout);
|
||||
}
|
||||
|
||||
this.get('session').hasWhatsNew().then((v) => {
|
||||
this.set('hasWhatsNew', v);
|
||||
});
|
||||
|
||||
let version = this.get('appMeta.version');
|
||||
|
||||
let self = this;
|
||||
let cacheBuster = + new Date();
|
||||
$.ajax({
|
||||
url: `https://storage.googleapis.com/documize/downloads/updates/${version}.html?cb=${cacheBuster}`,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
success: function (response) {
|
||||
self.set('newsContent', response);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
|
@ -80,6 +101,12 @@ export default Component.extend({
|
|||
let folder = this.get('store').peekRecord('folder', folderId);
|
||||
this.get('router').transitionTo('document', folderId, folder.get('slug'), documentId, 'document');
|
||||
}
|
||||
},
|
||||
|
||||
onShowWhatsNewModal() {
|
||||
this.modalOpen("#whats-new-modal", { "show": true });
|
||||
this.get('session').seenNewVersion();
|
||||
this.set('hasWhatsNew', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@ export default Model.extend({
|
|||
global: attr('boolean', { defaultValue: false }),
|
||||
accounts: attr(),
|
||||
groups: attr(),
|
||||
lastVersion: attr('string'),
|
||||
created: attr(),
|
||||
revised: attr(),
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
// https://documize.com
|
||||
|
||||
import { Promise as EmberPromise } from 'rsvp';
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import Controller from '@ember/controller';
|
||||
import NotifierMixin from "../../../mixins/notifier";
|
||||
|
@ -18,13 +17,13 @@ import NotifierMixin from "../../../mixins/notifier";
|
|||
|
||||
export default Controller.extend(NotifierMixin, {
|
||||
global: service(),
|
||||
appMeta: service(),
|
||||
appMeta: service(),
|
||||
session: service(),
|
||||
|
||||
actions: {
|
||||
onSave(data) {
|
||||
return new EmberPromise((resolve) => {
|
||||
if(!this.get('session.isGlobalAdmin')) {
|
||||
if (!this.get('session.isGlobalAdmin')) {
|
||||
resolve();
|
||||
} else {
|
||||
this.get('global').saveAuthConfig(data).then(() => {
|
||||
|
@ -39,14 +38,14 @@ export default Controller.extend(NotifierMixin, {
|
|||
this.get('global').syncExternalUsers().then((response) => {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onChange(data) {
|
||||
this.get('session').logout();
|
||||
this.set('appMeta.authProvider', data.authProvider);
|
||||
this.set('appMeta.authConfig', data.authConfig);
|
||||
window.location.href= '/';
|
||||
window.location.href = '/';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{{#toolbar/t-toolbar}}
|
||||
{{#toolbar/t-links}}
|
||||
{{#link-to "folders" class="link" tagName="li"}}Spaces{{/link-to}}
|
||||
{{#link-to "folders" class="link" tagName="li" }}Spaces{{/link-to}}
|
||||
{{/toolbar/t-links}}
|
||||
{{#toolbar/t-actions}}
|
||||
{{/toolbar/t-actions}}
|
||||
|
@ -14,27 +14,23 @@
|
|||
<div class="form-group mt-4">
|
||||
{{focus-input type="text" value=filter class="form-control mb-4" placeholder='a OR b, x AND y, "phrase mat*"'}}
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" id=checkId class="form-check-input" checked=matchDoc}} document title
|
||||
</label>
|
||||
{{input type="checkbox" id="search-1" class="form-check-input" checked=matchDoc}}
|
||||
<label class="form-check-label" for="search-1"> document title</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" id=checkId class="form-check-input" checked=matchContent}} content
|
||||
</label>
|
||||
{{input type="checkbox" id="search-2" class="form-check-input" checked=matchContent}}
|
||||
<label class="form-check-label" for="search-2"> content</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" id=checkId class="form-check-input" checked=matchTag}} tag name
|
||||
</label>
|
||||
{{input type="checkbox" id="search-3" class="form-check-input" checked=matchTag}}
|
||||
<label class="form-check-label" for="search-3"> tag name</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" id=checkId class="form-check-input" checked=matchFile}} attachment name
|
||||
</label>
|
||||
{{input type="checkbox" id="search-4" class="form-check-input" checked=matchFile}}
|
||||
<label class="form-check-label" for="search-4"> attachment name</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{search/search-results results=results}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
// https://documize.com
|
||||
|
||||
import $ from 'jquery';
|
||||
import { htmlSafe } from '@ember/string';
|
||||
import { resolve } from 'rsvp';
|
||||
import Service, { inject as service } from '@ember/service';
|
||||
|
@ -63,6 +64,7 @@ export default Service.extend({
|
|||
|
||||
return this.get('ajax').request('public/meta').then((response) => {
|
||||
this.setProperties(response);
|
||||
this.set('version', 'v' + this.get('version'));
|
||||
|
||||
if (requestedRoute === 'secure') {
|
||||
this.setProperties({
|
||||
|
@ -70,12 +72,32 @@ export default Service.extend({
|
|||
allowAnonymousAccess: true,
|
||||
secureMode: true
|
||||
});
|
||||
|
||||
|
||||
this.get('localStorage').clearAll();
|
||||
} else if (is.not.include(requestedUrl, '/auth/')) {
|
||||
this.get('localStorage').storeSessionItem('entryUrl', requestedUrl);
|
||||
}
|
||||
|
||||
let self = this;
|
||||
let cacheBuster = + new Date();
|
||||
$.getJSON(`https://storage.googleapis.com/documize/downloads/updates/meta.json?cb=${cacheBuster}`, function (versions) {
|
||||
let cv = 'v' + versions.community.version;
|
||||
let ev = 'v' + versions.enterprise.version;
|
||||
let re = self.get('edition');
|
||||
let rv = self.get('version');
|
||||
|
||||
self.set('communityLatest', cv);
|
||||
self.set('enterpriseLatest', ev);
|
||||
self.set('updateAvailable', false); // set to true for testing
|
||||
|
||||
if (re === 'Community' && rv < cv) {
|
||||
self.set('updateAvailable', true);
|
||||
}
|
||||
if (re === 'Enterprise' && rv < ev) {
|
||||
self.set('updateAvailable', true);
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed } from '@ember/object';
|
||||
import { Promise as EmberPromise } from 'rsvp';
|
||||
import SimpleAuthSession from 'ember-simple-auth/services/session';
|
||||
|
||||
export default SimpleAuthSession.extend({
|
||||
ajax: service(),
|
||||
appMeta: service(),
|
||||
userSvc: service('user'),
|
||||
store: service(),
|
||||
localStorage: service(),
|
||||
folderPermissions: null,
|
||||
|
@ -23,11 +25,11 @@ export default SimpleAuthSession.extend({
|
|||
isMac: false,
|
||||
isMobile: false,
|
||||
|
||||
hasAccounts: computed('isAuthenticated', 'session.content.authenticated.user', function() {
|
||||
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() {
|
||||
accounts: computed('hasAccounts', function () {
|
||||
return this.get('session.content.authenticated.user.accounts');
|
||||
}),
|
||||
|
||||
|
@ -35,7 +37,9 @@ export default SimpleAuthSession.extend({
|
|||
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);
|
||||
let um = this.get('store').push(data)
|
||||
|
||||
return um;
|
||||
}
|
||||
}),
|
||||
|
||||
|
@ -71,5 +75,21 @@ export default SimpleAuthSession.extend({
|
|||
|
||||
logout() {
|
||||
this.get('localStorage').clearAll();
|
||||
},
|
||||
|
||||
seenNewVersion() {
|
||||
this.get('userSvc').getUser(this.get('user.id')).then((user) => {
|
||||
user.set('lastVersion', this.get('appMeta.version'));
|
||||
this.get('userSvc').save(user);
|
||||
});
|
||||
},
|
||||
|
||||
// set what's new indicator
|
||||
hasWhatsNew() {
|
||||
return new EmberPromise((resolve) => {
|
||||
return this.get('userSvc').getUser(this.get('user.id')).then((user) => {
|
||||
resolve(user.get('lastVersion') !== this.get('appMeta.version'));
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
@import "section/plantuml.scss";
|
||||
@import "section/papertrail.scss";
|
||||
@import "section/wysiwyg.scss";
|
||||
@import "news.scss";
|
||||
@import "enterprise/all.scss";
|
||||
|
||||
// Bootstrap override that removes gutter space on smaller screens
|
||||
|
@ -39,4 +40,4 @@
|
|||
// width: 100%;
|
||||
// max-width: none;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
18
gui/app/styles/bootstrap.scss
vendored
18
gui/app/styles/bootstrap.scss
vendored
|
@ -101,8 +101,7 @@ $link-hover-decoration: none;
|
|||
@import "node_modules/bootstrap/scss/tooltip";
|
||||
@import "node_modules/bootstrap/scss/tables";
|
||||
@import "node_modules/bootstrap/scss/badge";
|
||||
// @import "node_modules/bootstrap/scss/navbar";
|
||||
// @import "node_modules/bootstrap/scss/images";
|
||||
|
||||
|
||||
.modal-80 {
|
||||
max-width: 80% !important;
|
||||
|
@ -111,3 +110,18 @@ $link-hover-decoration: none;
|
|||
body.modal-open {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.modal-header-white {
|
||||
background-color: $color-white !important;
|
||||
border: none !important;
|
||||
|
||||
> .close {
|
||||
background-color: $color-white !important;
|
||||
border: none !important;
|
||||
|
||||
> span {
|
||||
color: $color-gray;
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ $color-red: #9E0D1F;
|
|||
$color-green: #348A37;
|
||||
$color-blue: #2667af;
|
||||
$color-goldy: #FFD700;
|
||||
$color-orange: #FFAD15;
|
||||
|
||||
// widgets
|
||||
$color-checkbox: #2667af;
|
||||
|
@ -40,6 +41,7 @@ $color-symbol-box: #dce5e8;
|
|||
$color-symbol-icon: #a4b8be;
|
||||
$color-card: #F9F9F9;
|
||||
$color-stroke: #e1e1e1;
|
||||
$color-whats-new: #fc1530;
|
||||
|
||||
// Color utility classes for direct usage in HTML
|
||||
.color-white {
|
||||
|
@ -75,6 +77,12 @@ $color-stroke: #e1e1e1;
|
|||
.color-gold {
|
||||
color: $color-goldy !important;
|
||||
}
|
||||
.color-orange {
|
||||
color: $color-orange !important;
|
||||
}
|
||||
.color-whats-new {
|
||||
color: $color-whats-new !important;
|
||||
}
|
||||
|
||||
.background-color-white {
|
||||
background-color: $color-white !important;
|
||||
|
|
175
gui/app/styles/news.scss
Normal file
175
gui/app/styles/news.scss
Normal file
|
@ -0,0 +1,175 @@
|
|||
.product-update {
|
||||
text-align: left;
|
||||
margin: 50px 0;
|
||||
|
||||
> .update-summary {
|
||||
padding: 25px;
|
||||
border: 1px solid $color-orange;
|
||||
background-color: $color-off-white;
|
||||
@include border-radius(2px);
|
||||
|
||||
> .caption {
|
||||
font-weight: bold;
|
||||
font-size: 1.5rem;
|
||||
color: $color-orange;
|
||||
margin-bottom: 15px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
> .instructions {
|
||||
font-weight: normal;
|
||||
font-size: 1.3rem;
|
||||
color: $color-gray;
|
||||
}
|
||||
|
||||
> .version {
|
||||
margin: 30px 0 0 20px;
|
||||
font-size: 1.3rem;
|
||||
color: $color-gray;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> .changes {
|
||||
margin: 10px 0 0 40px;
|
||||
|
||||
> li {
|
||||
list-style-type: disc;
|
||||
padding: 5px 0;
|
||||
font-size: 1.2rem;
|
||||
color: $color-black;
|
||||
|
||||
> .tag-edition {
|
||||
margin: 10px 10px 10px 10px;
|
||||
padding: 5px 10px;
|
||||
background-color: $color-gray-light;
|
||||
color: $color-primary;
|
||||
font-weight: bold;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-about {
|
||||
text-align: center;
|
||||
margin: 30px 30px;
|
||||
|
||||
> .edition {
|
||||
font-weight: normal;
|
||||
font-size: 1.5rem;
|
||||
color: $color-black;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
> .version {
|
||||
font-weight: bold;
|
||||
font-size: 1.1rem;
|
||||
color: $color-gray;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
> .dotcom {
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
color: $color-link;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
> .copyright {
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
font-size: 1rem;
|
||||
color: $color-off-black;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
> .license {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
font-size: 1rem;
|
||||
color: $color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.update-available-dot {
|
||||
border-radius: 10px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: $color-orange;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.whats-new-dot {
|
||||
border-radius: 10px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: $color-whats-new;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.product-news {
|
||||
text-align: left;
|
||||
margin: 0 30px;
|
||||
|
||||
> h2 {
|
||||
margin: 0 0 10px 0;
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
color: $color-off-black;
|
||||
}
|
||||
|
||||
> .news-item {
|
||||
padding: 30px 0;
|
||||
border-bottom: 1px solid $color-border;
|
||||
text-align: center;
|
||||
|
||||
> .title {
|
||||
color: $color-primary;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
> .date {
|
||||
color: $color-gray;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
> .info {
|
||||
color: $color-black;
|
||||
font-size: 1.1rem;
|
||||
font-weight: normal;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
> .tag-edition {
|
||||
margin: 10px 10px 10px 10px;
|
||||
padding: 5px 10px;
|
||||
background-color: $color-off-white;
|
||||
color: $color-gray;
|
||||
font-weight: 700;
|
||||
font-size: 0.9rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
> img {
|
||||
max-width: 450px;
|
||||
max-height: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
> .action {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
color: $color-gray;
|
||||
font-weight: 800;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
}
|
|
@ -201,7 +201,7 @@
|
|||
display: inline-block;
|
||||
cursor: default;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
// overflow: hidden; // kills update dots
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
line-height: 34px;
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
</div>
|
||||
|
||||
<div class="view-customize">
|
||||
|
||||
<form class="mt-5">
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">Provider</label>
|
||||
<div class="col-sm-10">
|
||||
|
@ -62,7 +60,8 @@
|
|||
<label for="keycloak-admin-user" class="col-sm-2 col-form-label">Keycloak Username</label>
|
||||
<div class="col-sm-10">
|
||||
{{input id="keycloak-admin-user" type="text" value=keycloakConfig.adminUser class=(if KeycloakAdminUserError 'form-control is-invalid' 'form-control')}}
|
||||
<small class="form-text text-muted">Used to connect with Keycloak and sync users with Documize (create user under Master Realm and assign 'view-users' role against Realm specified above)</small>
|
||||
<small class="form-text text-muted">Used to connect with Keycloak and sync users with Documize (create user under Master Realm and assign 'view-users' role
|
||||
against Realm specified above)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
@ -75,24 +74,26 @@
|
|||
<div class="form-group row">
|
||||
<label for="keycloak-admin-password" class="col-sm-2 col-form-label">Logout</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" class="form-check-input" checked=keycloakConfig.disableLogout}}
|
||||
Hide the logout button for Keycloak users
|
||||
</label>
|
||||
<div class="form-check">
|
||||
{{input type="checkbox" class="form-check-input" id="keycloak-logout" checked=keycloakConfig.disableLogout}}
|
||||
<label class="form-check-label" for="keycloak-logout">
|
||||
Hide the logout button for Keycloak users
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="keycloak-admin-password" class="col-sm-2 col-form-label">Space Permission</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="form-check-label">
|
||||
{{input type="checkbox" class="form-check-input" checked=keycloakConfig.defaultPermissionAddSpace}}
|
||||
Can add spaces
|
||||
</label>
|
||||
<div class="form-check">
|
||||
{{input type="checkbox" class="form-check-input" id="keycloak-perm" checked=keycloakConfig.defaultPermissionAddSpace}}
|
||||
<label class="form-check-label" for="keycloak-perm">
|
||||
Can add spaces
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="btn btn-success mt-4" {{action 'onSave'}}>Save</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -26,10 +26,13 @@
|
|||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">Anonymous Access</label>
|
||||
<div class="col-sm-10">
|
||||
<label class="form-check-label">
|
||||
<input type="checkbox" class="form-check-input" id="allowAnonymousAccess" checked={{model.general.allowAnonymousAccess}} />
|
||||
Make content marked as "Everyone" available to anonymous users
|
||||
</label>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="allowAnonymousAccess" checked= {{model.general.allowAnonymousAccess}}
|
||||
/>
|
||||
<label class="form-check-label" for="allowAnonymousAccess">
|
||||
Make content marked as "Everyone" available to anonymous users
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
|
@ -37,7 +40,8 @@
|
|||
<div class="col-sm-10">
|
||||
{{input id="conversionEndpoint" type="text" value=model.general.conversionEndpoint class=(if hasConversionEndpointInputError 'form-control is-invalid' 'form-control')}}
|
||||
<small class="form-text text-muted">
|
||||
Endpoint for handling import/export (e.g. https://api.documize.com, <a href="https://docs.documize.com/s/WNEpptWJ9AABRnha/administration-guides/d/WO0pt_MXigAB6sJ7/general-options">view documentation</a>)
|
||||
Endpoint for handling import/export (e.g. https://api.documize.com,
|
||||
<a href="https://docs.documize.com/s/WNEpptWJ9AABRnha/administration-guides/d/WO0pt_MXigAB6sJ7/general-options">view documentation</a>)
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,21 +1,55 @@
|
|||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="view-customize">
|
||||
<h1 class="admin-heading">Product License</h1>
|
||||
<h2 class="sub-heading">Optional Enterprise Edition license</h2>
|
||||
<h1 class="admin-heading">{{appMeta.edition}} Edition {{appMeta.version}}</h1>
|
||||
<h2 class="sub-heading">Enterprise Edition unlocks
|
||||
<a class="" href="https://documize.com/pricing">premium capabilities and product support</a>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="view-customize">
|
||||
<form class="mt-5">
|
||||
<form class="mt-5 ">
|
||||
<div class="form-group row">
|
||||
<label for="smtp-host" class="col-sm-2 col-form-label">License Key</label>
|
||||
<div class="col-sm-10">
|
||||
{{textarea value=model.license rows="15" class=(if LicenseError 'form-control is-invalid' 'form-control')}}
|
||||
<small class="form-text text-muted">XML format</small>
|
||||
<label for="smtp-host " class="col-sm-2 col-form-label ">Enterprise Edition License Key</label>
|
||||
<div class="col-sm-10 ">
|
||||
{{textarea value=model.license rows="10" class=(if LicenseError 'form-control is-invalid' 'form-control')}}
|
||||
<small class="form-text text-muted ">XML format</small>
|
||||
{{#if appMeta.valid}}
|
||||
<p class="mt-2 color-green">Valid</p>
|
||||
{{else}}
|
||||
<p class="mt-2 color-red">Invalid</p>
|
||||
{{/if}}
|
||||
<div class="btn btn-success mt-3" {{action 'saveLicense'}}>Save</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-success mt-4" {{action 'saveLicense'}}>Save</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="product-update">
|
||||
<div class="update-summary">
|
||||
{{#if appMeta.updateAvailable}}
|
||||
<a href="https://documize.com/downloads" class="caption">New version available</a>
|
||||
<p class="instructions">
|
||||
To upgrade, replace existing binary and restart Documize. Migrate between Community and Enterprise editions seamlessly.
|
||||
</p>
|
||||
{{else}}
|
||||
<div class="caption">Release Summary</div>
|
||||
{{/if}}
|
||||
<p>
|
||||
<span class="color-off-black">Community Edition {{appMeta.communityLatest}}</span>
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-community-windows-amd64.exe" class="font-weight-bold">Windows</a> ·
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-community-linux-amd64" class="font-weight-bold">Linux</a> ·
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-community-darwin-amd64" class="font-weight-bold">macOS</a>
|
||||
</p>
|
||||
<p>
|
||||
<span class="color-off-black">Enterprise Edition {{appMeta.enterpriseLatest}}</span>
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-enterprise-windows-amd64.exe" class="font-weight-bold color-blue">Windows</a> ·
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-enterprise-linux-amd64" class="font-weight-bold color-blue">Linux</a> ·
|
||||
<a href="https://storage.googleapis.com/documize/downloads/documize-enterprise-darwin-amd64" class="font-weight-bold color-blue">macOS</a>
|
||||
</p>
|
||||
<div class="my-5" />
|
||||
{{{changelog}}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">SSL</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="form-check">
|
||||
<div class="form-check">
|
||||
{{input id="smtp-usessl" type="checkbox" checked=model.smtp.usessl class='form-check-input'}}
|
||||
<label class="form-check-label" for="smtp-usessl">Use SSL</label>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div id="nav-bar" class="nav-bar clearfix container-fluid">
|
||||
<div class="row no-gutters">
|
||||
<div class="col col-sm-9">
|
||||
{{#link-to "folders" class='nav-link'}}
|
||||
{{#link-to "folders" class='nav-link' }}
|
||||
<div class="nav-title">{{appMeta.title}}</div>
|
||||
<div class="nav-msg text-truncate">{{appMeta.message}}</div>
|
||||
{{/link-to}}
|
||||
|
@ -9,7 +9,7 @@
|
|||
<div class="col col-sm-3">
|
||||
<div class="nav-right">
|
||||
<div class="btn-group">
|
||||
{{#link-to "search" class="button-icon-white"}}
|
||||
{{#link-to "search" class="button-icon-white" }}
|
||||
<i class="material-icons">search</i>
|
||||
{{/link-to}}
|
||||
</div>
|
||||
|
@ -25,13 +25,13 @@
|
|||
{{#if hasSpacePins}}
|
||||
<h6 class="dropdown-header">Spaces</h6>
|
||||
{{#each spacePins as |pin|}}
|
||||
<a class="dropdown-item" href="#" {{action 'jumpToPin' pin}} data-id={{pin.id}} id="pin-{{pin.id}}">{{pin.pin}}</a>
|
||||
<a class="dropdown-item" href="#" {{action 'jumpToPin' pin}} data-id= {{pin.id}} id="pin-{{pin.id}}">{{pin.pin}}</a>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
{{#if hasDocumentPins}}
|
||||
<h6 class="dropdown-header">Documents</h6>
|
||||
{{#each documentPins as |pin|}}
|
||||
<a class="dropdown-item" href="#" {{action 'jumpToPin' pin}} data-id={{pin.id}} id="pin-{{pin.id}}">{{pin.pin}}</a>
|
||||
<a class="dropdown-item" href="#" {{action 'jumpToPin' pin}} data-id= {{pin.id}} id="pin-{{pin.id}}">{{pin.pin}}</a>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -42,22 +42,38 @@
|
|||
<div class="btn-group">
|
||||
<div class="button-gravatar-white align-text-bottom" id="profile-button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{session.user.initials}}
|
||||
{{#if hasWhatsNew}}
|
||||
<div class="whats-new-dot" />
|
||||
{{/if}}
|
||||
{{#if session.isAdmin}}
|
||||
{{#if appMeta.updateAvailable}}
|
||||
<div class="update-available-dot" />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="profile-button">
|
||||
{{#link-to 'profile' class="dropdown-item"}}Profile{{/link-to}}
|
||||
{{#link-to 'profile' class="dropdown-item" }}Profile{{/link-to}}
|
||||
{{#if session.isAdmin}}
|
||||
{{#link-to 'customize.general' class="dropdown-item"}}Settings{{/link-to}}
|
||||
{{#link-to 'customize.general' class="dropdown-item" }}Settings{{/link-to}}
|
||||
{{/if}}
|
||||
<div class="dropdown-divider"></div>
|
||||
{{#if session.isAdmin}}
|
||||
{{#if appMeta.updateAvailable}}
|
||||
{{#link-to 'customize.license' class="dropdown-item font-weight-bold color-orange" }}Update available{{/link-to}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<a href="#" class="dropdown-item {{if hasWhatsNew 'color-whats-new font-weight-bold'}}" {{action 'onShowWhatsNewModal'}}>What's New</a>
|
||||
<a href="#" class="dropdown-item" data-toggle="modal" data-target="#about-documize-modal" data-backdrop="static">About Documize</a>
|
||||
{{#if enableLogout}}
|
||||
<div class="dropdown-divider"></div>
|
||||
{{#link-to 'auth.logout' class="dropdown-item"}}Logout{{/link-to}}
|
||||
{{#link-to 'auth.logout' class="dropdown-item" }}Logout{{/link-to}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="button-icon-gap" />
|
||||
<div class="btn-group">
|
||||
{{#link-to 'auth.login' class="button-icon-white "}}
|
||||
{{#link-to 'auth.login' class="button-icon-white " }}
|
||||
<i class="material-icons">lock_open</i>
|
||||
{{/link-to}}
|
||||
</div>
|
||||
|
@ -66,3 +82,67 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if session.authenticated}}
|
||||
<div id="whats-new-modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-header modal-header-white">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true" data-dismiss="modal" aria-label="Close">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<div class="product-news">
|
||||
<h2>What's New</h2>
|
||||
|
||||
{{{newsContent}}}
|
||||
|
||||
<div class="action">
|
||||
Have an idea? Suggestion or feedback? <a href="mailto:support@documize.com">Get in touch!</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="about-documize-modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<div class="product-about">
|
||||
<div class="edition">
|
||||
Documize {{appMeta.edition}} Edition
|
||||
</div>
|
||||
<div class="version">
|
||||
{{appMeta.version}}
|
||||
</div>
|
||||
<div class="dotcom">
|
||||
<a href="https://documize.com">https://documize.com</a>
|
||||
</div>
|
||||
{{#if (eq appMeta.edition 'Community')}}
|
||||
<div class="copyright">
|
||||
© Documize Inc. All rights reserved.
|
||||
</div>
|
||||
<div class="license">
|
||||
<br/>
|
||||
<br/> This software (Documize Community Edition) is licensed under
|
||||
<a href="http://www.gnu.org/licenses/agpl-3.0.en.html">GNU AGPL v3</a>
|
||||
You can operate outside the AGPL restrictions by purchasing Documize Enterprise Edition and obtaining a commercial licenseby
|
||||
contacting
|
||||
<a href="mailto:sales@documize.com">sales@documize.com</a>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
14
meta.json
14
meta.json
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"community": {
|
||||
"version": "1.59.0",
|
||||
"major": 1,
|
||||
"minor": 59,
|
||||
"patch": 0
|
||||
},
|
||||
"enterprise": {
|
||||
"version": "1.61.0",
|
||||
"major": 1,
|
||||
"minor": 61,
|
||||
"patch": 0
|
||||
}
|
||||
}
|
|
@ -22,20 +22,21 @@ import (
|
|||
// User defines a login.
|
||||
type User struct {
|
||||
model.BaseEntity
|
||||
Firstname string `json:"firstname"`
|
||||
Lastname string `json:"lastname"`
|
||||
Email string `json:"email"`
|
||||
Initials string `json:"initials"`
|
||||
Active bool `json:"active"`
|
||||
Editor bool `json:"editor"`
|
||||
Admin bool `json:"admin"`
|
||||
ViewUsers bool `json:"viewUsers"`
|
||||
Global bool `json:"global"`
|
||||
Password string `json:"-"`
|
||||
Salt string `json:"-"`
|
||||
Reset string `json:"-"`
|
||||
Accounts []account.Account `json:"accounts"`
|
||||
Groups []group.Record `json:"groups"`
|
||||
Firstname string `json:"firstname"`
|
||||
Lastname string `json:"lastname"`
|
||||
Email string `json:"email"`
|
||||
Initials string `json:"initials"`
|
||||
Active bool `json:"active"`
|
||||
Editor bool `json:"editor"`
|
||||
Admin bool `json:"admin"`
|
||||
ViewUsers bool `json:"viewUsers"`
|
||||
Global bool `json:"global"`
|
||||
Password string `json:"-"`
|
||||
Salt string `json:"-"`
|
||||
Reset string `json:"-"`
|
||||
LastVersion string `json:"lastVersion"`
|
||||
Accounts []account.Account `json:"accounts"`
|
||||
Groups []group.Record `json:"groups"`
|
||||
}
|
||||
|
||||
// ProtectSecrets blanks sensitive data.
|
||||
|
|
|
@ -144,6 +144,7 @@ func (m *middleware) Authorize(w http.ResponseWriter, r *http.Request, next http
|
|||
rc.AppURL = r.Host
|
||||
rc.Subdomain = organization.GetSubdomainFromHost(r)
|
||||
rc.SSL = r.TLS != nil
|
||||
rc.AppVersion = fmt.Sprintf("v%s", m.Runtime.Product.Version)
|
||||
|
||||
// get user IP from request
|
||||
i := strings.LastIndex(r.RemoteAddr, ":")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue