aboutsummaryrefslogtreecommitdiff
path: root/client/js
diff options
context:
space:
mode:
authorShyam Sunder2018-06-25 10:47:20 -0400
committerMarcin Kurczewski2018-06-27 21:20:03 +0200
commit3972b902d840e54bd4f8dd47a9d13bc20ee22c65 (patch)
tree22a2d05fdc2a89a6c6595ef2a56d0747d761dc2a /client/js
parent2bf361c64a46d575533f68f8ced88e037f887335 (diff)
client: fetch configurations from server at runtime
Permissions, regex filters, app title, email info, and safety now fetched using server's Info API
Diffstat (limited to 'client/js')
-rw-r--r--client/js/api.js48
-rw-r--r--client/js/controllers/home_controller.js2
-rw-r--r--client/js/controllers/post_list_controller.js11
-rw-r--r--client/js/controllers/post_upload_controller.js3
-rw-r--r--client/js/controllers/top_navigation_controller.js17
-rw-r--r--client/js/controllers/user_controller.js1
-rw-r--r--client/js/controls/post_edit_sidebar_control.js3
-rw-r--r--client/js/controls/post_readonly_sidebar_control.js2
-rw-r--r--client/js/main.js83
-rw-r--r--client/js/models/post_list.js2
-rw-r--r--client/js/models/top_navigation.js8
-rw-r--r--client/js/views/help_view.js4
-rw-r--r--client/js/views/login_view.js12
-rw-r--r--client/js/views/not_found_view.js1
-rw-r--r--client/js/views/password_reset_view.js6
-rw-r--r--client/js/views/post_merge_view.js1
-rw-r--r--client/js/views/registration_view.js6
-rw-r--r--client/js/views/tag_edit_view.js4
-rw-r--r--client/js/views/tag_merge_view.js4
-rw-r--r--client/js/views/user_edit_view.js6
20 files changed, 133 insertions, 91 deletions
diff --git a/client/js/api.js b/client/js/api.js
index 3623045..ba06f19 100644
--- a/client/js/api.js
+++ b/client/js/api.js
@@ -8,6 +8,7 @@ const progress = require('./util/progress.js');
const uri = require('./util/uri.js');
let fileTokens = {};
+let remoteConfig = null;
class Api extends events.EventTarget {
constructor() {
@@ -65,14 +66,53 @@ class Api extends events.EventTarget {
return this._wrappedRequest(url, request.delete, data, {}, options);
}
+ fetchConfig() {
+ if (remoteConfig === null) {
+ return this.get(uri.formatApiLink('info'))
+ .then(response => {
+ remoteConfig = response.config;
+ });
+ } else {
+ return Promise.resolve();
+ }
+ }
+
+ getName() {
+ return remoteConfig.name;
+ }
+
+ getTagNameRegex() {
+ return remoteConfig.tagNameRegex;
+ }
+
+ getPasswordRegex() {
+ return remoteConfig.passwordRegex;
+ }
+
+ getUserNameRegex() {
+ return remoteConfig.userNameRegex;
+ }
+
+ getContactEmail() {
+ return remoteConfig.contactEmail;
+ }
+
+ canSendMails() {
+ return !!remoteConfig.canSendMails;
+ }
+
+ safetyEnabled() {
+ return !!remoteConfig.enableSafety;
+ }
+
hasPrivilege(lookup) {
let minViableRank = null;
- for (let privilege of Object.keys(config.privileges)) {
- if (!privilege.startsWith(lookup)) {
+ for (let p of Object.keys(remoteConfig.privileges)) {
+ if (!p.startsWith(lookup)) {
continue;
}
- const rankName = config.privileges[privilege];
- const rankIndex = this.allRanks.indexOf(rankName);
+ const rankIndex = this.allRanks.indexOf(
+ remoteConfig.privileges[p]);
if (minViableRank === null || rankIndex < minViableRank) {
minViableRank = rankIndex;
}
diff --git a/client/js/controllers/home_controller.js b/client/js/controllers/home_controller.js
index b7590a0..cc22ca9 100644
--- a/client/js/controllers/home_controller.js
+++ b/client/js/controllers/home_controller.js
@@ -12,7 +12,7 @@ class HomeController {
topNavigation.setTitle('Home');
this._homeView = new HomeView({
- name: config.name,
+ name: api.getName(),
version: config.meta.version,
buildDate: config.meta.buildDate,
canListSnapshots: api.hasPrivilege('snapshots:list'),
diff --git a/client/js/controllers/post_list_controller.js b/client/js/controllers/post_list_controller.js
index f60cb8b..fd1adfe 100644
--- a/client/js/controllers/post_list_controller.js
+++ b/client/js/controllers/post_list_controller.js
@@ -1,6 +1,5 @@
'use strict';
-const config = require('../config.js');
const router = require('../router.js');
const api = require('../api.js');
const settings = require('../models/settings.js');
@@ -33,9 +32,9 @@ class PostListController {
this._headerView = new PostsHeaderView({
hostNode: this._pageController.view.pageHeaderHolderNode,
parameters: ctx.parameters,
- enableSafety: config.enableSafety,
- canBulkEditTags: api.hasPrivilege('posts:bulkEdit:tags'),
- canBulkEditSafety: api.hasPrivilege('posts:bulkEdit:safety'),
+ enableSafety: api.safetyEnabled(),
+ canBulkEditTags: api.hasPrivilege('posts:bulk-edit:tags'),
+ canBulkEditSafety: api.hasPrivilege('posts:bulk-edit:safety'),
bulkEdit: {
tags: this._bulkEditTags
},
@@ -97,9 +96,9 @@ class PostListController {
pageRenderer: pageCtx => {
Object.assign(pageCtx, {
canViewPosts: api.hasPrivilege('posts:view'),
- canBulkEditTags: api.hasPrivilege('posts:bulkEdit:tags'),
+ canBulkEditTags: api.hasPrivilege('posts:bulk-edit:tags'),
canBulkEditSafety:
- api.hasPrivilege('posts:bulkEdit:safety'),
+ api.hasPrivilege('posts:bulk-edit:safety'),
bulkEdit: {
tags: this._bulkEditTags,
},
diff --git a/client/js/controllers/post_upload_controller.js b/client/js/controllers/post_upload_controller.js
index 9dfdb4a..ccd6f94 100644
--- a/client/js/controllers/post_upload_controller.js
+++ b/client/js/controllers/post_upload_controller.js
@@ -1,7 +1,6 @@
'use strict';
const api = require('../api.js');
-const config = require('../config.js');
const router = require('../router.js');
const uri = require('../util/uri.js');
const misc = require('../util/misc.js');
@@ -31,7 +30,7 @@ class PostUploadController {
this._view = new PostUploadView({
canUploadAnonymously: api.hasPrivilege('posts:create:anonymous'),
canViewPosts: api.hasPrivilege('posts:view'),
- enableSafety: config.enableSafety,
+ enableSafety: api.safetyEnabled(),
});
this._view.addEventListener('change', e => this._evtChange(e));
this._view.addEventListener('submit', e => this._evtSubmit(e));
diff --git a/client/js/controllers/top_navigation_controller.js b/client/js/controllers/top_navigation_controller.js
index 0f56ddc..fdf8117 100644
--- a/client/js/controllers/top_navigation_controller.js
+++ b/client/js/controllers/top_navigation_controller.js
@@ -1,21 +1,22 @@
'use strict';
const api = require('../api.js');
-const config = require('../config.js');
const topNavigation = require('../models/top_navigation.js');
const TopNavigationView = require('../views/top_navigation_view.js');
class TopNavigationController {
constructor() {
- this._topNavigationView = new TopNavigationView();
+ api.fetchConfig().then(() => {
+ this._topNavigationView = new TopNavigationView();
- topNavigation.addEventListener(
- 'activate', e => this._evtActivate(e));
+ topNavigation.addEventListener(
+ 'activate', e => this._evtActivate(e));
- api.addEventListener('login', e => this._evtAuthChange(e));
- api.addEventListener('logout', e => this._evtAuthChange(e));
+ api.addEventListener('login', e => this._evtAuthChange(e));
+ api.addEventListener('logout', e => this._evtAuthChange(e));
- this._render();
+ this._render();
+ });
}
_evtAuthChange(e) {
@@ -65,7 +66,7 @@ class TopNavigationController {
this._updateNavigationFromPrivileges();
this._topNavigationView.render({
items: topNavigation.getAll(),
- name: config.name
+ name: api.getName()
});
this._topNavigationView.activate(
topNavigation.activeItem ? topNavigation.activeItem.key : '');
diff --git a/client/js/controllers/user_controller.js b/client/js/controllers/user_controller.js
index d042e41..48989af 100644
--- a/client/js/controllers/user_controller.js
+++ b/client/js/controllers/user_controller.js
@@ -4,7 +4,6 @@ const router = require('../router.js');
const api = require('../api.js');
const uri = require('../util/uri.js');
const misc = require('../util/misc.js');
-const config = require('../config.js');
const views = require('../util/views.js');
const User = require('../models/user.js');
const UserToken = require('../models/user_token.js');
diff --git a/client/js/controls/post_edit_sidebar_control.js b/client/js/controls/post_edit_sidebar_control.js
index 38dded2..dd8b66d 100644
--- a/client/js/controls/post_edit_sidebar_control.js
+++ b/client/js/controls/post_edit_sidebar_control.js
@@ -1,7 +1,6 @@
'use strict';
const api = require('../api.js');
-const config = require('../config.js');
const events = require('../events.js');
const misc = require('../util/misc.js');
const views = require('../util/views.js');
@@ -26,7 +25,7 @@ class PostEditSidebarControl extends events.EventTarget {
views.replaceContent(this._hostNode, template({
post: this._post,
- enableSafety: config.enableSafety,
+ enableSafety: api.safetyEnabled(),
hasClipboard: document.queryCommandSupported('copy'),
canEditPostSafety: api.hasPrivilege('posts:edit:safety'),
canEditPostSource: api.hasPrivilege('posts:edit:source'),
diff --git a/client/js/controls/post_readonly_sidebar_control.js b/client/js/controls/post_readonly_sidebar_control.js
index bb51e69..579a38e 100644
--- a/client/js/controls/post_readonly_sidebar_control.js
+++ b/client/js/controls/post_readonly_sidebar_control.js
@@ -21,7 +21,7 @@ class PostReadonlySidebarControl extends events.EventTarget {
views.replaceContent(this._hostNode, template({
post: this._post,
- enableSafety: config.enableSafety,
+ enableSafety: api.safetyEnabled(),
canListPosts: api.hasPrivilege('posts:list'),
canEditPosts: api.hasPrivilege('posts:edit'),
canViewTags: api.hasPrivilege('tags:view'),
diff --git a/client/js/main.js b/client/js/main.js
index 71284f8..5ddf26f 100644
--- a/client/js/main.js
+++ b/client/js/main.js
@@ -26,46 +26,51 @@ router.enter(
next();
});
-// register controller routes
-let controllers = [];
-controllers.push(require('./controllers/home_controller.js'));
-controllers.push(require('./controllers/help_controller.js'));
-controllers.push(require('./controllers/auth_controller.js'));
-controllers.push(require('./controllers/password_reset_controller.js'));
-controllers.push(require('./controllers/comments_controller.js'));
-controllers.push(require('./controllers/snapshots_controller.js'));
-controllers.push(require('./controllers/post_detail_controller.js'));
-controllers.push(require('./controllers/post_main_controller.js'));
-controllers.push(require('./controllers/post_list_controller.js'));
-controllers.push(require('./controllers/post_upload_controller.js'));
-controllers.push(require('./controllers/tag_controller.js'));
-controllers.push(require('./controllers/tag_list_controller.js'));
-controllers.push(require('./controllers/tag_categories_controller.js'));
-controllers.push(require('./controllers/settings_controller.js'));
-controllers.push(require('./controllers/user_controller.js'));
-controllers.push(require('./controllers/user_list_controller.js'));
-controllers.push(require('./controllers/user_registration_controller.js'));
-
-// 404 controller needs to be registered last
-controllers.push(require('./controllers/not_found_controller.js'));
-
-for (let controller of controllers) {
- controller(router);
-}
-
const tags = require('./tags.js');
const api = require('./api.js');
tags.refreshCategoryColorMap(); // we don't care about errors
-api.loginFromCookies().then(() => {
- router.start();
- }, error => {
- if (window.location.href.indexOf('login') !== -1) {
- api.forget();
+
+api.fetchConfig().then(() => {
+ // register controller routes
+ let controllers = [];
+ controllers.push(require('./controllers/home_controller.js'));
+ controllers.push(require('./controllers/help_controller.js'));
+ controllers.push(require('./controllers/auth_controller.js'));
+ controllers.push(require('./controllers/password_reset_controller.js'));
+ controllers.push(require('./controllers/comments_controller.js'));
+ controllers.push(require('./controllers/snapshots_controller.js'));
+ controllers.push(require('./controllers/post_detail_controller.js'));
+ controllers.push(require('./controllers/post_main_controller.js'));
+ controllers.push(require('./controllers/post_list_controller.js'));
+ controllers.push(require('./controllers/post_upload_controller.js'));
+ controllers.push(require('./controllers/tag_controller.js'));
+ controllers.push(require('./controllers/tag_list_controller.js'));
+ controllers.push(require('./controllers/tag_categories_controller.js'));
+ controllers.push(require('./controllers/settings_controller.js'));
+ controllers.push(require('./controllers/user_controller.js'));
+ controllers.push(require('./controllers/user_list_controller.js'));
+ controllers.push(require('./controllers/user_registration_controller.js'));
+
+ // 404 controller needs to be registered last
+ controllers.push(require('./controllers/not_found_controller.js'));
+
+ for (let controller of controllers) {
+ controller(router);
+ }
+}, error => {
+ window.alert('Could not fetch basic configuration from server');
+}).then(() => {
+ api.loginFromCookies().then(() => {
router.start();
- } else {
- const ctx = router.start('/');
- ctx.controller.showError(
- 'An error happened while trying to log you in: ' +
- error.message);
- }
- });
+ }, error => {
+ if (window.location.href.indexOf('login') !== -1) {
+ api.forget();
+ router.start();
+ } else {
+ const ctx = router.start('/');
+ ctx.controller.showError(
+ 'An error happened while trying to log you in: ' +
+ error.message);
+ }
+ });
+});
diff --git a/client/js/models/post_list.js b/client/js/models/post_list.js
index 2e3c6fc..2bfd056 100644
--- a/client/js/models/post_list.js
+++ b/client/js/models/post_list.js
@@ -37,7 +37,7 @@ class PostList extends AbstractList {
static _decorateSearchQuery(text) {
const browsingSettings = settings.get();
const disabledSafety = [];
- if (config.enableSafety) {
+ if (api.safetyEnabled()) {
for (let key of Object.keys(browsingSettings.listPosts)) {
if (browsingSettings.listPosts[key] === false) {
disabledSafety.push(key);
diff --git a/client/js/models/top_navigation.js b/client/js/models/top_navigation.js
index ebb3753..a7c726d 100644
--- a/client/js/models/top_navigation.js
+++ b/client/js/models/top_navigation.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
class TopNavigationItem {
constructor(accessKey, title, url, available, imageUrl) {
@@ -53,8 +53,10 @@ class TopNavigation extends events.EventTarget {
}
setTitle(title) {
- document.oldTitle = null;
- document.title = config.name + (title ? (' – ' + title) : '');
+ api.fetchConfig().then(() => {
+ document.oldTitle = null;
+ document.title = api.getName() + (title ? (' – ' + title) : '');
+ });
}
showAll() {
diff --git a/client/js/views/help_view.js b/client/js/views/help_view.js
index 4938b23..11f6a39 100644
--- a/client/js/views/help_view.js
+++ b/client/js/views/help_view.js
@@ -1,6 +1,6 @@
'use strict';
-const config = require('../config.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const template = views.getTemplate('help');
@@ -26,7 +26,7 @@ class HelpView {
const sourceNode = template();
const ctx = {
- name: config.name,
+ name: api.getName(),
};
section = section || 'about';
diff --git a/client/js/views/login_view.js b/client/js/views/login_view.js
index 7d97982..2c05332 100644
--- a/client/js/views/login_view.js
+++ b/client/js/views/login_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const template = views.getTemplate('login');
@@ -12,15 +12,15 @@ class LoginView extends events.EventTarget {
this._hostNode = document.getElementById('content-holder');
views.replaceContent(this._hostNode, template({
- userNamePattern: config.userNameRegex,
- passwordPattern: config.passwordRegex,
- canSendMails: config.canSendMails,
+ userNamePattern: api.getUserNameRegex(),
+ passwordPattern: api.getPasswordRegex(),
+ canSendMails: api.canSendMails(),
}));
views.syncScrollPosition();
views.decorateValidator(this._formNode);
- this._userNameInputNode.setAttribute('pattern', config.userNameRegex);
- this._passwordInputNode.setAttribute('pattern', config.passwordRegex);
+ this._userNameInputNode.setAttribute('pattern', api.getUserNameRegex());
+ this._passwordInputNode.setAttribute('pattern', api.getPasswordRegex());
this._formNode.addEventListener('submit', e => {
e.preventDefault();
this.dispatchEvent(new CustomEvent('submit', {
diff --git a/client/js/views/not_found_view.js b/client/js/views/not_found_view.js
index 8b5a103..487613b 100644
--- a/client/js/views/not_found_view.js
+++ b/client/js/views/not_found_view.js
@@ -1,6 +1,5 @@
'use strict';
-const config = require('../config.js');
const views = require('../util/views.js');
const template = views.getTemplate('not-found');
diff --git a/client/js/views/password_reset_view.js b/client/js/views/password_reset_view.js
index 25409c7..685fe5a 100644
--- a/client/js/views/password_reset_view.js
+++ b/client/js/views/password_reset_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const template = views.getTemplate('password-reset');
@@ -12,8 +12,8 @@ class PasswordResetView extends events.EventTarget {
this._hostNode = document.getElementById('content-holder');
views.replaceContent(this._hostNode, template({
- canSendMails: config.canSendMails,
- contactEmail: config.contactEmail,
+ canSendMails: api.canSendMails(),
+ contactEmail: api.getContactEmail(),
}));
views.syncScrollPosition();
diff --git a/client/js/views/post_merge_view.js b/client/js/views/post_merge_view.js
index 04ed21d..3e987b3 100644
--- a/client/js/views/post_merge_view.js
+++ b/client/js/views/post_merge_view.js
@@ -1,6 +1,5 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
const views = require('../util/views.js');
diff --git a/client/js/views/registration_view.js b/client/js/views/registration_view.js
index fb924c2..48034dd 100644
--- a/client/js/views/registration_view.js
+++ b/client/js/views/registration_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const template = views.getTemplate('user-registration');
@@ -11,8 +11,8 @@ class RegistrationView extends events.EventTarget {
super();
this._hostNode = document.getElementById('content-holder');
views.replaceContent(this._hostNode, template({
- userNamePattern: config.userNameRegex,
- passwordPattern: config.passwordRegex,
+ userNamePattern: api.getUserNameRegex(),
+ passwordPattern: api.getPasswordRegex(),
}));
views.syncScrollPosition();
views.decorateValidator(this._formNode);
diff --git a/client/js/views/tag_edit_view.js b/client/js/views/tag_edit_view.js
index 77c7cef..5b517d4 100644
--- a/client/js/views/tag_edit_view.js
+++ b/client/js/views/tag_edit_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const misc = require('../util/misc.js');
const views = require('../util/views.js');
const TagInputControl = require('../controls/tag_input_control.js');
@@ -64,7 +64,7 @@ class TagEditView extends events.EventTarget {
}
_evtNameInput(e) {
- const regex = new RegExp(config.tagNameRegex);
+ const regex = new RegExp(api.getTagNameRegex());
const list = misc.splitByWhitespace(this._namesFieldNode.value);
if (!list.length) {
diff --git a/client/js/views/tag_merge_view.js b/client/js/views/tag_merge_view.js
index 1228680..c975a50 100644
--- a/client/js/views/tag_merge_view.js
+++ b/client/js/views/tag_merge_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const TagAutoCompleteControl =
require('../controls/tag_auto_complete_control.js');
@@ -14,7 +14,7 @@ class TagMergeView extends events.EventTarget {
this._tag = ctx.tag;
this._hostNode = ctx.hostNode;
- ctx.tagNamePattern = config.tagNameRegex;
+ ctx.tagNamePattern = api.getTagNameRegex();
views.replaceContent(this._hostNode, template(ctx));
views.decorateValidator(this._formNode);
diff --git a/client/js/views/user_edit_view.js b/client/js/views/user_edit_view.js
index 28208ea..8a6f1a4 100644
--- a/client/js/views/user_edit_view.js
+++ b/client/js/views/user_edit_view.js
@@ -1,7 +1,7 @@
'use strict';
-const config = require('../config.js');
const events = require('../events.js');
+const api = require('../api.js');
const views = require('../util/views.js');
const FileDropperControl = require('../controls/file_dropper_control.js');
@@ -11,8 +11,8 @@ class UserEditView extends events.EventTarget {
constructor(ctx) {
super();
- ctx.userNamePattern = config.userNameRegex + /|^$/.source;
- ctx.passwordPattern = config.passwordRegex + /|^$/.source;
+ ctx.userNamePattern = api.getUserNameRegex() + /|^$/.source;
+ ctx.passwordPattern = api.getPasswordRegex() + /|^$/.source;
this._user = ctx.user;
this._hostNode = ctx.hostNode;

© 2015 - 2026 Jakob L. Kreuze