mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-12-17 05:50:25 +01:00
Compare commits
29 Commits
normalize-
...
v1.18.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bba9e7c0f7 | ||
|
|
8047900170 | ||
|
|
32b38643f8 | ||
|
|
37ba8a2c8e | ||
|
|
35f0c559c0 | ||
|
|
d19a273ce9 | ||
|
|
7624af5769 | ||
|
|
00a6b05f89 | ||
|
|
b46dcd9243 | ||
|
|
1a375000a7 | ||
|
|
1f8f2e9168 | ||
|
|
edae9522b5 | ||
|
|
7ff2b7fbb1 | ||
|
|
22e74dc0bb | ||
|
|
27acf19325 | ||
|
|
0f29433baf | ||
|
|
ebe7f11d0b | ||
|
|
c248805165 | ||
|
|
830cddfb40 | ||
|
|
abbbc3d7c2 | ||
|
|
8593ea87e9 | ||
|
|
1d401329ee | ||
|
|
9e52236973 | ||
|
|
eff03e4b57 | ||
|
|
854c078b73 | ||
|
|
36653525bd | ||
|
|
0409403f5b | ||
|
|
839673d321 | ||
|
|
d220d1d461 |
@@ -138,6 +138,7 @@
|
|||||||
"disableEmailSubscriptions": 0,
|
"disableEmailSubscriptions": 0,
|
||||||
"emailConfirmInterval": 10,
|
"emailConfirmInterval": 10,
|
||||||
"removeEmailNotificationImages": 0,
|
"removeEmailNotificationImages": 0,
|
||||||
|
"sendValidationEmail": 1,
|
||||||
"includeUnverifiedEmails": 0,
|
"includeUnverifiedEmails": 0,
|
||||||
"emailPrompt": 1,
|
"emailPrompt": 1,
|
||||||
"inviteExpiration": 7,
|
"inviteExpiration": 7,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "nodebb",
|
"name": "nodebb",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"description": "NodeBB Forum",
|
"description": "NodeBB Forum",
|
||||||
"version": "1.18.5",
|
"version": "1.18.6",
|
||||||
"homepage": "http://www.nodebb.org",
|
"homepage": "http://www.nodebb.org",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"cli-graph": "^3.2.2",
|
"cli-graph": "^3.2.2",
|
||||||
"clipboard": "^2.0.6",
|
"clipboard": "^2.0.6",
|
||||||
"colors": "^1.4.0",
|
"colors": "1.4.0",
|
||||||
"commander": "^7.1.0",
|
"commander": "^7.1.0",
|
||||||
"compare-versions": "3.6.0",
|
"compare-versions": "3.6.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
"nodebb-plugin-emoji": "^3.5.0",
|
"nodebb-plugin-emoji": "^3.5.0",
|
||||||
"nodebb-plugin-emoji-android": "2.0.5",
|
"nodebb-plugin-emoji-android": "2.0.5",
|
||||||
"nodebb-plugin-markdown": "8.14.4",
|
"nodebb-plugin-markdown": "8.14.4",
|
||||||
"nodebb-plugin-mentions": "3.0.2",
|
"nodebb-plugin-mentions": "3.0.3",
|
||||||
"nodebb-plugin-spam-be-gone": "0.7.11",
|
"nodebb-plugin-spam-be-gone": "0.7.11",
|
||||||
"nodebb-rewards-essentials": "0.2.0",
|
"nodebb-rewards-essentials": "0.2.0",
|
||||||
"nodebb-theme-lavender": "5.3.1",
|
"nodebb-theme-lavender": "5.3.1",
|
||||||
@@ -182,4 +182,4 @@
|
|||||||
"url": "https://github.com/barisusakli"
|
"url": "https://github.com/barisusakli"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@
|
|||||||
"subscriptions.hour-help": "Please enter a number representing the hour to send scheduled email digests (e.g. <code>0</code> for midnight, <code>17</code> for 5:00pm). Keep in mind that this is the hour according to the server itself, and may not exactly match your system clock.<br /> The approximate server time is: <span id=\"serverTime\"></span><br /> The next daily digest is scheduled to be sent <span id=\"nextDigestTime\"></span>",
|
"subscriptions.hour-help": "Please enter a number representing the hour to send scheduled email digests (e.g. <code>0</code> for midnight, <code>17</code> for 5:00pm). Keep in mind that this is the hour according to the server itself, and may not exactly match your system clock.<br /> The approximate server time is: <span id=\"serverTime\"></span><br /> The next daily digest is scheduled to be sent <span id=\"nextDigestTime\"></span>",
|
||||||
"notifications.remove-images": "Remove images from email notifications",
|
"notifications.remove-images": "Remove images from email notifications",
|
||||||
"require-email-address": "Require new users to specify an email address",
|
"require-email-address": "Require new users to specify an email address",
|
||||||
"require-email-address-warning": "By default, users can opt-out of entering an email address. Enabling this option means they have to enter an email address in order to proceed with registration. <strong>It does not ensure user will enter a real email address, nor even an address they own.</strong>",
|
"require-email-address-warning": "By default, users can opt-out of entering an email address by leaving the field blank. Enabling this option means they have to enter an email address in order to proceed with registration. <strong>It does not ensure user will enter a real email address, nor even an address they own.</strong>",
|
||||||
|
"send-validation-email": "Send validation emails when an email is added or changed",
|
||||||
"include-unverified-emails": "Send emails to recipients who have not explicitly confirmed their emails",
|
"include-unverified-emails": "Send emails to recipients who have not explicitly confirmed their emails",
|
||||||
"include-unverified-warning": "By default, users with emails associated with their account have already been verified, but there are situations where this is not the case (e.g. SSO logins, grandfathered users, etc). <strong>Enable this setting at your own risk</strong> – sending emails to unverified addresses may be a violation of regional anti-spam laws.",
|
"include-unverified-warning": "By default, users with emails associated with their account have already been verified, but there are situations where this is not the case (e.g. SSO logins, grandfathered users, etc). <strong>Enable this setting at your own risk</strong> – sending emails to unverified addresses may be a violation of regional anti-spam laws.",
|
||||||
"prompt": "Prompt users to enter or confirm their emails",
|
"prompt": "Prompt users to enter or confirm their emails",
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ ajaxify = window.ajaxify || {};
|
|||||||
};
|
};
|
||||||
|
|
||||||
ajaxify.loadTemplate = function (template, callback) {
|
ajaxify.loadTemplate = function (template, callback) {
|
||||||
require([config.assetBaseUrl + '/templates/' + template + '.js'], callback, function (err) {
|
require([config.asset_base_url + '/templates/' + template + '.js'], callback, function (err) {
|
||||||
console.error('Unable to load template: ' + template);
|
console.error('Unable to load template: ' + template);
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ define('forum/topic/posts', [
|
|||||||
if (!isPreviousPostAdded && data.posts[0].selfPost) {
|
if (!isPreviousPostAdded && data.posts[0].selfPost) {
|
||||||
return ajaxify.go('post/' + data.posts[0].pid);
|
return ajaxify.go('post/' + data.posts[0].pid);
|
||||||
}
|
}
|
||||||
const repliesSelector = $('[component="post"]:not([data-index=0]), [component="topic/event"]');
|
const repliesSelector = $('[component="topic"]>[component="post"]:not([data-index=0]), [component="topic"]>[component="topic/event"]');
|
||||||
createNewPosts(data, repliesSelector, direction, false, function (html) {
|
createNewPosts(data, repliesSelector, direction, false, function (html) {
|
||||||
if (html) {
|
if (html) {
|
||||||
html.addClass('new');
|
html.addClass('new');
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ define('forum/topic/threadTools', [
|
|||||||
|
|
||||||
threadEl.find('[component="post"][data-uid="' + app.user.uid + '"].deleted [component="post/tools"]').toggleClass('hidden', isLocked);
|
threadEl.find('[component="post"][data-uid="' + app.user.uid + '"].deleted [component="post/tools"]').toggleClass('hidden', isLocked);
|
||||||
|
|
||||||
$('.topic-header [component="topic/locked"]').toggleClass('hidden', !data.isLocked);
|
$('[component="topic/labels"] [component="topic/locked"]').toggleClass('hidden', !data.isLocked);
|
||||||
$('[component="post/tools"] .dropdown-menu').html('');
|
$('[component="post/tools"] .dropdown-menu').html('');
|
||||||
ajaxify.data.locked = data.isLocked;
|
ajaxify.data.locked = data.isLocked;
|
||||||
|
|
||||||
@@ -334,7 +334,7 @@ define('forum/topic/threadTools', [
|
|||||||
|
|
||||||
components.get('topic/pin').toggleClass('hidden', data.pinned).parent().attr('hidden', data.pinned ? '' : null);
|
components.get('topic/pin').toggleClass('hidden', data.pinned).parent().attr('hidden', data.pinned ? '' : null);
|
||||||
components.get('topic/unpin').toggleClass('hidden', !data.pinned).parent().attr('hidden', !data.pinned ? '' : null);
|
components.get('topic/unpin').toggleClass('hidden', !data.pinned).parent().attr('hidden', !data.pinned ? '' : null);
|
||||||
const icon = $('.topic-header [component="topic/pinned"]');
|
const icon = $('[component="topic/labels"] [component="topic/pinned"]');
|
||||||
icon.toggleClass('hidden', !data.pinned);
|
icon.toggleClass('hidden', !data.pinned);
|
||||||
if (data.pinned) {
|
if (data.pinned) {
|
||||||
icon.translateAttr('title', (
|
icon.translateAttr('title', (
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
(function (factory) {
|
(function (factory) {
|
||||||
function loadClient(language, namespace) {
|
function loadClient(language, namespace) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
jQuery.getJSON([config.assetBaseUrl, 'language', language, namespace].join('/') + '.json?' + config['cache-buster'], function (data) {
|
jQuery.getJSON([config.asset_base_url, 'language', language, namespace].join('/') + '.json?' + config['cache-buster'], function (data) {
|
||||||
const payload = {
|
const payload = {
|
||||||
language: language,
|
language: language,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"updateTypes": ["minor", "patch", "pin", "digest"],
|
"updateTypes": ["minor", "patch", "pin", "digest"],
|
||||||
"automerge": true
|
"automerge": true,
|
||||||
|
"excludePackageNames": ["colors"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ module.exports = function (Categories) {
|
|||||||
let cids = await findCids(query, data.hardCap);
|
let cids = await findCids(query, data.hardCap);
|
||||||
|
|
||||||
const result = await plugins.hooks.fire('filter:categories.search', {
|
const result = await plugins.hooks.fire('filter:categories.search', {
|
||||||
|
data: data,
|
||||||
cids: cids,
|
cids: cids,
|
||||||
uid: uid,
|
uid: uid,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const apiController = module.exports;
|
|||||||
|
|
||||||
const relative_path = nconf.get('relative_path');
|
const relative_path = nconf.get('relative_path');
|
||||||
const upload_url = nconf.get('upload_url');
|
const upload_url = nconf.get('upload_url');
|
||||||
|
const asset_base_url = nconf.get('asset_base_url');
|
||||||
const socketioTransports = nconf.get('socket.io:transports') || ['polling', 'websocket'];
|
const socketioTransports = nconf.get('socket.io:transports') || ['polling', 'websocket'];
|
||||||
const socketioOrigins = nconf.get('socket.io:origins');
|
const socketioOrigins = nconf.get('socket.io:origins');
|
||||||
const websocketAddress = nconf.get('socket.io:address') || '';
|
const websocketAddress = nconf.get('socket.io:address') || '';
|
||||||
@@ -22,7 +23,8 @@ apiController.loadConfig = async function (req) {
|
|||||||
const config = {
|
const config = {
|
||||||
relative_path,
|
relative_path,
|
||||||
upload_url,
|
upload_url,
|
||||||
assetBaseUrl: `${relative_path}/assets`,
|
asset_base_url,
|
||||||
|
assetBaseUrl: asset_base_url, // deprecate in 1.20.x
|
||||||
siteTitle: validator.escape(String(meta.config.title || meta.config.browserTitle || 'NodeBB')),
|
siteTitle: validator.escape(String(meta.config.title || meta.config.browserTitle || 'NodeBB')),
|
||||||
browserTitle: validator.escape(String(meta.config.browserTitle || meta.config.title || 'NodeBB')),
|
browserTitle: validator.escape(String(meta.config.browserTitle || meta.config.title || 'NodeBB')),
|
||||||
titleLayout: (meta.config.titleLayout || '{pageTitle} | {browserTitle}').replace(/{/g, '{').replace(/}/g, '}'),
|
titleLayout: (meta.config.titleLayout || '{pageTitle} | {browserTitle}').replace(/{/g, '{').replace(/}/g, '}'),
|
||||||
|
|||||||
@@ -123,6 +123,11 @@ helpers.buildTerms = function (url, term, query) {
|
|||||||
helpers.notAllowed = async function (req, res, error) {
|
helpers.notAllowed = async function (req, res, error) {
|
||||||
({ error } = await plugins.hooks.fire('filter:helpers.notAllowed', { req, res, error }));
|
({ error } = await plugins.hooks.fire('filter:helpers.notAllowed', { req, res, error }));
|
||||||
|
|
||||||
|
await plugins.hooks.fire('response:helpers.notAllowed', { req, res, error });
|
||||||
|
if (res.headersSent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (req.loggedIn || req.uid === -1) {
|
if (req.loggedIn || req.uid === -1) {
|
||||||
if (res.locals.isAPI) {
|
if (res.locals.isAPI) {
|
||||||
if (req.originalUrl.startsWith(`${relative_path}/api/v3`)) {
|
if (req.originalUrl.startsWith(`${relative_path}/api/v3`)) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ helpers.buildBodyClass = function (req, res, templateData = {}) {
|
|||||||
try {
|
try {
|
||||||
p = slugify(decodeURIComponent(p));
|
p = slugify(decodeURIComponent(p));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
winston.error(`Error decoding URI: ${p}`);
|
||||||
winston.error(err.stack);
|
winston.error(err.stack);
|
||||||
p = '';
|
p = '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ function loadConfig(configFile) {
|
|||||||
nconf.set('secure', urlObject.protocol === 'https:');
|
nconf.set('secure', urlObject.protocol === 'https:');
|
||||||
nconf.set('use_port', !!urlObject.port);
|
nconf.set('use_port', !!urlObject.port);
|
||||||
nconf.set('relative_path', relativePath);
|
nconf.set('relative_path', relativePath);
|
||||||
|
if (!nconf.get('asset_base_url')) {
|
||||||
|
nconf.set('asset_base_url', `${relativePath}/assets`);
|
||||||
|
}
|
||||||
nconf.set('port', nconf.get('PORT') || nconf.get('port') || urlObject.port || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
|
nconf.set('port', nconf.get('PORT') || nconf.get('port') || urlObject.port || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
|
||||||
|
|
||||||
// cookies don't provide isolation by port: http://stackoverflow.com/a/16328399/122353
|
// cookies don't provide isolation by port: http://stackoverflow.com/a/16328399/122353
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ module.exports = function (SocketCategories) {
|
|||||||
const result = await categories.search({
|
const result = await categories.search({
|
||||||
uid: uid,
|
uid: uid,
|
||||||
query: data.search,
|
query: data.search,
|
||||||
|
qs: data.query,
|
||||||
paginate: false,
|
paginate: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let matchedCids = result.categories.map(c => c.cid);
|
let matchedCids = result.categories.map(c => c.cid);
|
||||||
// no need to filter if all 3 states are used
|
// no need to filter if all 3 states are used
|
||||||
const filterByWatchState = !Object.values(categories.watchStates)
|
const filterByWatchState = !Object.values(categories.watchStates)
|
||||||
|
|||||||
@@ -88,7 +88,9 @@ module.exports = function (Topics) {
|
|||||||
Topics.checkTitle(data.title);
|
Topics.checkTitle(data.title);
|
||||||
await Topics.validateTags(data.tags, data.cid, uid);
|
await Topics.validateTags(data.tags, data.cid, uid);
|
||||||
data.tags = await Topics.filterTags(data.tags, data.cid);
|
data.tags = await Topics.filterTags(data.tags, data.cid);
|
||||||
Topics.checkContent(data.content);
|
if (!data.fromQueue) {
|
||||||
|
Topics.checkContent(data.content);
|
||||||
|
}
|
||||||
|
|
||||||
const [categoryExists, canCreate, canTag] = await Promise.all([
|
const [categoryExists, canCreate, canTag] = await Promise.all([
|
||||||
categories.exists(data.cid),
|
categories.exists(data.cid),
|
||||||
@@ -165,13 +167,13 @@ module.exports = function (Topics) {
|
|||||||
data.cid = topicData.cid;
|
data.cid = topicData.cid;
|
||||||
|
|
||||||
await guestHandleValid(data);
|
await guestHandleValid(data);
|
||||||
if (!data.fromQueue) {
|
|
||||||
await user.isReadyToPost(uid, data.cid);
|
|
||||||
}
|
|
||||||
if (data.content) {
|
if (data.content) {
|
||||||
data.content = utils.rtrim(data.content);
|
data.content = utils.rtrim(data.content);
|
||||||
}
|
}
|
||||||
Topics.checkContent(data.content);
|
if (!data.fromQueue) {
|
||||||
|
await user.isReadyToPost(uid, data.cid);
|
||||||
|
Topics.checkContent(data.content);
|
||||||
|
}
|
||||||
|
|
||||||
// For replies to scheduled topics, don't have a timestamp older than topic's itself
|
// For replies to scheduled topics, don't have a timestamp older than topic's itself
|
||||||
if (topicData.scheduled) {
|
if (topicData.scheduled) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
|
const winston = require('winston');
|
||||||
|
|
||||||
const user = require('./index');
|
const user = require('./index');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
@@ -69,6 +70,11 @@ UserEmail.sendValidationEmail = async function (uid, options) {
|
|||||||
* - force, sends email even if it is too soon to send another
|
* - force, sends email even if it is too soon to send another
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (meta.config.sendValidationEmail !== 1) {
|
||||||
|
winston.verbose(`[user/email] Validation email for uid ${uid} not sent due to config settings`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
// Fallback behaviour (email passed in as second argument)
|
// Fallback behaviour (email passed in as second argument)
|
||||||
@@ -110,6 +116,7 @@ UserEmail.sendValidationEmail = async function (uid, options) {
|
|||||||
await db.expireAt(`confirm:${confirm_code}`, Math.floor((Date.now() / 1000) + (60 * 60 * 24)));
|
await db.expireAt(`confirm:${confirm_code}`, Math.floor((Date.now() / 1000) + (60 * 60 * 24)));
|
||||||
const username = await user.getUserField(uid, 'username');
|
const username = await user.getUserField(uid, 'username');
|
||||||
|
|
||||||
|
winston.verbose(`[user/email] Validation email for uid ${uid} sent to ${options.email}`);
|
||||||
events.log({
|
events.log({
|
||||||
type: 'email-confirmation-sent',
|
type: 'email-confirmation-sent',
|
||||||
uid,
|
uid,
|
||||||
|
|||||||
@@ -20,13 +20,6 @@
|
|||||||
<input type="text" class="form-control input-lg" id="email:from_name" data-field="email:from_name" placeholder="NodeBB" /><br />
|
<input type="text" class="form-control input-lg" id="email:from_name" data-field="email:from_name" placeholder="NodeBB" /><br />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
|
||||||
<label for="removeEmailNotificationImages" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
|
||||||
<input class="mdl-switch__input" type="checkbox" id="removeEmailNotificationImages" data-field="removeEmailNotificationImages" name="removeEmailNotificationImages" />
|
|
||||||
<span class="mdl-switch__label">[[admin/settings/email:notifications.remove-images]]</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label for="requireEmailAddress" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="requireEmailAddress" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" id="requireEmailAddress" data-field="requireEmailAddress" name="requireEmailAddress" />
|
<input class="mdl-switch__input" type="checkbox" id="requireEmailAddress" data-field="requireEmailAddress" name="requireEmailAddress" />
|
||||||
@@ -35,6 +28,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="help-block">[[admin/settings/email:require-email-address-warning]]</p>
|
<p class="help-block">[[admin/settings/email:require-email-address-warning]]</p>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label for="sendValidationEmail" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
|
<input class="mdl-switch__input" type="checkbox" id="sendValidationEmail" data-field="sendValidationEmail" name="sendValidationEmail" />
|
||||||
|
<span class="mdl-switch__label">[[admin/settings/email:send-validation-email]]</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label for="includeUnverifiedEmails" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label for="includeUnverifiedEmails" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" id="includeUnverifiedEmails" data-field="includeUnverifiedEmails" name="includeUnverifiedEmails" />
|
<input class="mdl-switch__input" type="checkbox" id="includeUnverifiedEmails" data-field="includeUnverifiedEmails" name="includeUnverifiedEmails" />
|
||||||
@@ -50,6 +50,13 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block">[[admin/settings/email:prompt-help]]</p>
|
<p class="help-block">[[admin/settings/email:prompt-help]]</p>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label for="removeEmailNotificationImages" class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
|
<input class="mdl-switch__input" type="checkbox" id="removeEmailNotificationImages" data-field="removeEmailNotificationImages" name="removeEmailNotificationImages" />
|
||||||
|
<span class="mdl-switch__label">[[admin/settings/email:notifications.remove-images]]</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ nconf.defaults({
|
|||||||
const urlObject = url.parse(nconf.get('url'));
|
const urlObject = url.parse(nconf.get('url'));
|
||||||
const relativePath = urlObject.pathname !== '/' ? urlObject.pathname : '';
|
const relativePath = urlObject.pathname !== '/' ? urlObject.pathname : '';
|
||||||
nconf.set('relative_path', relativePath);
|
nconf.set('relative_path', relativePath);
|
||||||
|
nconf.set('asset_base_url', `${relativePath}/assets`);
|
||||||
nconf.set('upload_path', path.join(nconf.get('base_dir'), nconf.get('upload_path')));
|
nconf.set('upload_path', path.join(nconf.get('base_dir'), nconf.get('upload_path')));
|
||||||
nconf.set('upload_url', '/assets/uploads');
|
nconf.set('upload_url', '/assets/uploads');
|
||||||
nconf.set('url_parsed', urlObject);
|
nconf.set('url_parsed', urlObject);
|
||||||
|
|||||||
Reference in New Issue
Block a user