Allow channel path to be customizable
We now allow server operators to customize the /r/ part of the channel links The new config option in the template is commented and the config module validates and will terminate with status 78 if an improper value is used. We've also dropped some old cruft and uses a more elegant method to assign CHANNEL.name Resolves #668
This commit is contained in:
parent
00a65a1584
commit
6d4558c978
18 changed files with 71 additions and 75 deletions
|
|
@ -61,6 +61,7 @@ function initPasswordResetCleanup(Server) {
|
|||
}
|
||||
|
||||
function initChannelDumper(Server) {
|
||||
const chanPath = Config.get('channel-path');
|
||||
var CHANNEL_SAVE_INTERVAL = parseInt(Config.get("channel-save-interval"))
|
||||
* 60000;
|
||||
setInterval(function () {
|
||||
|
|
@ -70,9 +71,9 @@ function initChannelDumper(Server) {
|
|||
return Promise.delay(wait).then(() => {
|
||||
if (!chan.dead && chan.users && chan.users.length > 0) {
|
||||
return chan.saveState().tap(() => {
|
||||
LOGGER.info(`Saved /r/${chan.name}`);
|
||||
LOGGER.info(`Saved /${chanPath}/${chan.name}`);
|
||||
}).catch(err => {
|
||||
LOGGER.error(`Failed to save /r/${chan.name}: ${err.stack}`);
|
||||
LOGGER.error(`Failed to save /${chanPath}/${chan.name}: ${err.stack}`);
|
||||
});
|
||||
}
|
||||
}).catch(error => {
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ function fixOldChandump(data) {
|
|||
}
|
||||
|
||||
function migrate(src, dest, opts) {
|
||||
const chanPath = Config.get('channel-path');
|
||||
|
||||
return src.listChannels().then(names => {
|
||||
return Promise.reduce(names, (_, name) => {
|
||||
// A long time ago there was a bug where CyTube would save a different
|
||||
|
|
@ -143,11 +145,11 @@ function migrate(src, dest, opts) {
|
|||
});
|
||||
return dest.save(name, data);
|
||||
}).then(() => {
|
||||
console.log(`Migrated /r/${name}`);
|
||||
console.log(`Migrated /${chanPath}/${name}`);
|
||||
}).catch(ChannelNotFoundError, err => {
|
||||
console.log(`Skipping /r/${name} (not present in the database)`);
|
||||
console.log(`Skipping /${chanPath}/${name} (not present in the database)`);
|
||||
}).catch(err => {
|
||||
console.error(`Failed to migrate /r/${name}: ${err.stack}`);
|
||||
console.error(`Failed to migrate /${chanPath}/${name}: ${err.stack}`);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -70,7 +70,12 @@ var defaults = {
|
|||
"from-name": "CyTube Services"
|
||||
},
|
||||
"youtube-v3-key": "",
|
||||
"channel-blacklist": [],
|
||||
"channel-path": "r",
|
||||
"channel-save-interval": 5,
|
||||
"channel-storage": {
|
||||
type: "file"
|
||||
},
|
||||
"max-channels-per-user": 5,
|
||||
"max-accounts-per-ip": 5,
|
||||
"guest-login-delay": 60,
|
||||
|
|
@ -102,7 +107,6 @@ var defaults = {
|
|||
"max-items": 4000,
|
||||
"update-interval": 5
|
||||
},
|
||||
"channel-blacklist": [],
|
||||
ffmpeg: {
|
||||
enabled: false,
|
||||
"ffprobe-exec": "ffprobe"
|
||||
|
|
@ -114,9 +118,6 @@ var defaults = {
|
|||
"user": "nobody",
|
||||
"timeout": 15
|
||||
},
|
||||
"channel-storage": {
|
||||
type: "file"
|
||||
},
|
||||
"service-socket": {
|
||||
enabled: false,
|
||||
socket: "service.sock"
|
||||
|
|
@ -390,6 +391,12 @@ function preprocessConfig(cfg) {
|
|||
});
|
||||
cfg["channel-blacklist"] = tbl;
|
||||
|
||||
/* Check channel path */
|
||||
if(!/^[-\w]+$/.test(cfg["channel-blacklist"])){
|
||||
LOGGER.error("Channel paths may only use the same characters as usernames and channel names.");
|
||||
process.exit(78); // sysexits.h for bad config
|
||||
}
|
||||
|
||||
if (cfg["link-domain-blacklist"].length > 0) {
|
||||
cfg["link-domain-blacklist-regex"] = new RegExp(
|
||||
cfg["link-domain-blacklist"].join("|").replace(/\./g, "\\."), "gi");
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ var Server = function () {
|
|||
self.announcement = null;
|
||||
self.infogetter = null;
|
||||
self.servers = {};
|
||||
self.chanPath = Config.get('channel-path');
|
||||
|
||||
// backend init
|
||||
var initModule;
|
||||
|
|
@ -264,7 +265,7 @@ Server.prototype.unloadChannel = function (chan, options) {
|
|||
|
||||
if (!options.skipSave) {
|
||||
chan.saveState().catch(error => {
|
||||
LOGGER.error(`Failed to save /r/${chan.name} for unload: ${error.stack}`);
|
||||
LOGGER.error(`Failed to save /${this.chanPath}/${chan.name} for unload: ${error.stack}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -354,9 +355,9 @@ Server.prototype.shutdown = function () {
|
|||
Promise.map(this.channels, channel => {
|
||||
try {
|
||||
return channel.saveState().tap(() => {
|
||||
LOGGER.info(`Saved /r/${channel.name}`);
|
||||
LOGGER.info(`Saved /${this.chanPath}/${channel.name}`);
|
||||
}).catch(err => {
|
||||
LOGGER.error(`Failed to save /r/${channel.name}: ${err.stack}`);
|
||||
LOGGER.error(`Failed to save /${this.chanPath}/${channel.name}: ${err.stack}`);
|
||||
});
|
||||
} catch (error) {
|
||||
LOGGER.error(`Failed to save channel: ${error.stack}`);
|
||||
|
|
@ -391,7 +392,7 @@ Server.prototype.handlePartitionMapChange = function () {
|
|||
});
|
||||
this.unloadChannel(channel, { skipSave: true });
|
||||
}).catch(error => {
|
||||
LOGGER.error(`Failed to unload /r/${channel.name} for ` +
|
||||
LOGGER.error(`Failed to unload /${this.chanPath}/${channel.name} for ` +
|
||||
`partition map flip: ${error.stack}`);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ function merge(locals, res) {
|
|||
loginDomain: Config.get("https.enabled") ? Config.get("https.full-address")
|
||||
: Config.get("http.full-address"),
|
||||
csrfToken: typeof res.req.csrfToken === 'function' ? res.req.csrfToken() : '',
|
||||
baseUrl: getBaseUrl(res)
|
||||
baseUrl: getBaseUrl(res),
|
||||
channelPath: Config.get("channel-path"),
|
||||
};
|
||||
if (typeof locals !== "object") {
|
||||
return _locals;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import { sendPug } from '../pug';
|
|||
import * as HTTPStatus from '../httpstatus';
|
||||
import { HTTPError } from '../../errors';
|
||||
|
||||
export default function initialize(app, ioConfig) {
|
||||
app.get('/r/:channel', (req, res) => {
|
||||
export default function initialize(app, ioConfig, chanPath) {
|
||||
app.get(`/${chanPath}/:channel`, (req, res) => {
|
||||
if (!req.params.channel || !CyTubeUtil.isValidChannelName(req.params.channel)) {
|
||||
throw new HTTPError(`"${sanitizeText(req.params.channel)}" is not a valid ` +
|
||||
'channel name.', { status: HTTPStatus.NOT_FOUND });
|
||||
|
|
|
|||
|
|
@ -132,6 +132,8 @@ module.exports = {
|
|||
* Initializes webserver callbacks
|
||||
*/
|
||||
init: function (app, webConfig, ioConfig, clusterClient, channelIndex, session) {
|
||||
const chanPath = Config.get('channel-path');
|
||||
|
||||
app.use((req, res, next) => {
|
||||
counters.add("http:request", 1);
|
||||
next();
|
||||
|
|
@ -147,7 +149,7 @@ module.exports = {
|
|||
}
|
||||
app.use(cookieParser(webConfig.getCookieSecret()));
|
||||
app.use(csrf.init(webConfig.getCookieDomain()));
|
||||
app.use('/r/:channel', require('./middleware/ipsessioncookie').ipSessionCookieMiddleware);
|
||||
app.use(`/${chanPath}/:channel`, require('./middleware/ipsessioncookie').ipSessionCookieMiddleware);
|
||||
initializeLog(app);
|
||||
require('./middleware/authorize')(app, session);
|
||||
|
||||
|
|
@ -176,7 +178,7 @@ module.exports = {
|
|||
LOGGER.info('Enabled express-minify for CSS and JS');
|
||||
}
|
||||
|
||||
require('./routes/channel')(app, ioConfig);
|
||||
require('./routes/channel')(app, ioConfig, chanPath);
|
||||
require('./routes/index')(app, channelIndex, webConfig.getMaxIndexEntries());
|
||||
app.get('/sioconfig(.json)?', handleLegacySocketConfig);
|
||||
require('./routes/socketconfig')(app, clusterClient);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue