Customization!

Add ability to control page title and color scheme.

Also, partially implements manual triggering of cronjobs.

Fixes #18
This commit is contained in:
Dessa Simpson 2021-02-21 23:25:23 -07:00
parent 1c34b3f013
commit 6495e1c8ef
6 changed files with 294 additions and 40 deletions

View file

@ -30,6 +30,7 @@ const app = express();
app.use(version.checkVersionMiddleware);
app.use(express.static('public'));
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(session({
secret: config.sessionSecret,
saveUninitialized: false,
@ -189,6 +190,101 @@ app.post("/api/updateRequestScoreModifier", async (request, response) => {
.catch((e: any) => errorHandler(request,response,e));
});
app.post("/api/updatePageTitle", async (request, response) => {
if (request.session) await validateApiToken(request.session);
if (!request.session || !request.session.user) {
response.status(401);
response.send("Session expired; please log in again");
return;
}
var streamerid = await db.query(queries.getStreamerId).then((result: pg.QueryResult) => result.rows[0]['userid']);
if (request.session.user.id != streamerid) {
response.status(401);
response.send("You are not the streamer");
return;
}
if (!request.body.pageTitle) {
response.status(400);
response.send("Missing pageTitle");
return;
}
var pageTitle = request.body.pageTitle as string;
response.type('text/plain');
pageTitle = pageTitle.replace(/[&<>"']/g, function(m) {
switch (m) {
case '&':
return '&amp;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '"':
return '&quot;';
case "'":
return '&apos;';
default:
return '';
}
});
await db.query(Object.assign(queries.updatePageTitle,{ values: [pageTitle] }))
.catch((e: any) => errorHandler(request,response,e));
response.status(200);
response.send('Successfully updated page title');
});
app.post("/api/updateColors", async (request, response) => {
if (request.session) await validateApiToken(request.session);
if (!request.session || !request.session.user) {
response.status(401);
response.send("Session expired; please log in again");
return;
}
var streamerid = await db.query(queries.getStreamerId).then((result: pg.QueryResult) => result.rows[0]['userid']);
if (request.session.user.id != streamerid) {
response.status(401);
response.send("You are not the streamer");
return;
}
if (!request.body.bg) {
response.status(400);
response.send("Missing bg");
return;
}
if (!request.body.fg) {
response.status(400);
response.send("Missing fg");
return;
}
type Colors = { [key: string]: { [key: string]: string} }
var colors: Colors = { bg: {}, fg: {} };
console.log(JSON.stringify(request.body,null,2));
for (var color of ['primary','table','navbar','error']) {
var setcolor = request.body.bg[color];
if (/^#[0-9a-fA-F]{6}$/.test(setcolor)) {
colors.bg[color] = setcolor
} else {
response.status(400);
response.send(`Color 'bg.${color}' missing or invalid`)
return;
}
}
for (var color of ['primary','ahover','title']) {
var setcolor = request.body.fg[color];
if (/^#[0-9a-fA-F]{6}$/.test(setcolor)) {
colors.fg[color] = setcolor
} else {
response.status(400);
response.send(`Color 'fg.${color}' missing or invalid`)
return;
}
}
response.type('text/plain');
await db.query(Object.assign(queries.updateColors,{ values: [JSON.stringify(colors)] }))
.catch((e: any) => errorHandler(request,response,e));
response.status(200);
response.send('Successfully updated colors');
});
app.post("/api/deleteRequest", async (request, response) => {
if (request.session) await validateApiToken(request.session);
if (!request.session || !request.session.user) {
@ -266,6 +362,37 @@ app.post("/api/deleteVote", async (request,response) => {
.catch((e: any) => errorHandler(request,response,e));
});
app.get("/api/cronRequest", async (request, response) => {
if (request.session) await validateApiToken(request.session);
if (!request.session || !request.session.user) {
response.status(401);
response.send("Session expired; please log in again");
return;
}
var streamerid = await db.query(queries.getStreamerId).then((result: pg.QueryResult) => result.rows[0]['userid']);
if (request.session.user.id != streamerid) {
response.status(401);
response.send("You are not the streamer");
return;
}
if (!request.query.job) {
response.status(400);
response.send("Missing job");
return;
}
var job = request.body.job as string;
try {
cron.validateJob(job)
} catch (e) {
response.status(400);
response.send("Invalid job")
return;
}
response.type('text/plain');
cron.request(job).catch((e: any) => errorHandler(request,response,e));
});
// Twitch callback
app.get("/callback", async (request, response) => {
if (request.query.error) {
@ -302,7 +429,7 @@ app.get("/callback", async (request, response) => {
app.get("/", async (request, response) => {
if (request.session) await validateApiToken(request.session);
var streamerInfo = await db.query(queries.getStreamerInfo).then((result: pg.QueryResult) => result.rows[0]);
var config = await db.query(queries.getConfig).then((result: pg.QueryResult) => result.rows[0]);
var streamerConfig = await db.query(queries.getConfig).then((result: pg.QueryResult) => result.rows[0]);
if (typeof streamerInfo == 'undefined') {
response.redirect(307, `https://id.twitch.tv/oauth2/authorize?client_id=${config.twitchClientId}&redirect_uri=${config.urlPrefix}/callback&response_type=code&scope=channel:read:subscriptions moderation:read`);
return;
@ -312,7 +439,7 @@ app.get("/", async (request, response) => {
loggedIn: false,
clientId: config.twitchClientId,
urlPrefix: config.urlPrefix,
pageTitle: config.title,
pageTitle: streamerConfig.title,
streamerName: streamerInfo['displayname'],
streamerProfilePicture: streamerInfo['imageurl']
});
@ -324,9 +451,10 @@ app.get("/", async (request, response) => {
userProfilePicture: request.session.user.profile_image_url,
validStates: validStates,
isStreamer: streamerInfo['userid'] == request.session.user.id,
pageTitle: config.title,
pageTitle: streamerConfig.title,
streamerName: streamerInfo['displayname'],
streamerProfilePicture: streamerInfo['imageurl']
streamerProfilePicture: streamerInfo['imageurl'],
colors: streamerConfig.colors
});
}
});
@ -334,7 +462,6 @@ app.get("/", async (request, response) => {
app.get("/colors.css", async (_request, response) => {
var streamerInfo = await db.query(queries.getStreamerInfo).then((result: pg.QueryResult) => result.rows[0]);
var colors = await db.query(queries.getConfig).then((result: pg.QueryResult) => result.rows[0]['colors']);
console.log(colors);
if (typeof streamerInfo == 'undefined') return;
response.contentType("text/css");
response.render('colors.eta', colors);