Customization!
Add ability to control page title and color scheme. Also, partially implements manual triggering of cronjobs. Fixes #18
This commit is contained in:
parent
1c34b3f013
commit
6495e1c8ef
6 changed files with 294 additions and 40 deletions
137
src/app.ts
137
src/app.ts
|
@ -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 '&';
|
||||
case '<':
|
||||
return '<';
|
||||
case '>':
|
||||
return '>';
|
||||
case '"':
|
||||
return '"';
|
||||
case "'":
|
||||
return ''';
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue