Add VOD management page and the ability to delete the user's own vods

merge-requests/8/head
knotteye 4 years ago
parent 0b4a7d6321
commit 4628deec1c
  1. 21
      src/api.ts
  2. 36
      src/http.ts
  3. 14
      templates/managevods.njk
  4. 1
      templates/vods.njk

@ -1,7 +1,8 @@
import * as db from "./database"
import { config } from "./config";
import {unlink} from "fs";
async function register(name: string, password: string, confirm: string) {
async function register(name: string, password: string, confirm: string): Promise<object> {
if(!config['satyr']['registration']) return {"error":"registration disabled"};
if(name.includes(';') || name.includes(' ') || name.includes('\'')) return {"error":"illegal characters"};
if(password !== confirm) return {"error":"mismatched passwords"};
@ -16,7 +17,7 @@ async function register(name: string, password: string, confirm: string) {
return {"error":""};
}
async function update(fields: object){
async function update(fields: object): Promise<object>{
if(!fields['title'] && !fields['bio'] && (fields['rec'] !== 'true' && fields['rec'] !== 'false')) return {"error":"no valid fields specified"};
let qs: string = "";
let f: boolean = false;
@ -33,12 +34,13 @@ async function update(fields: object){
await db.query('UPDATE users,user_meta SET'+qs+' WHERE users.username='+db.raw.escape(fields['name'])+' AND user_meta.username='+db.raw.escape(fields['name']));
return {"success":""};
}
async function updateChat(fields: object){
async function updateChat(fields: object): Promise<object>{
await db.query('UPDATE chat_integration SET xmpp='+db.raw.escape(fields['xmpp'])+', discord='+db.raw.escape(fields['discord'])+', irc='+db.raw.escape(fields['irc'])+', twitch='+db.raw.escape(fields['twitch'])+' WHERE username='+db.raw.escape(fields['name']));
return {"success":""};
}
async function changepwd(name: string, password: string, newpwd: string){
async function changepwd(name: string, password: string, newpwd: string): Promise<object>{
if(!name || !password || !newpwd) return {"error":"Insufficient parameters"};
let auth: boolean = await db.validatePassword(name, password);
if(!auth) return {"error":"Username or Password Incorrect"};
@ -47,7 +49,7 @@ async function changepwd(name: string, password: string, newpwd: string){
return {"success":""};
}
async function changesk(name: string){
async function changesk(name: string): Promise<object>{
let key: string = await db.genKey();
await db.query('UPDATE users set stream_key='+db.raw.escape(key)+'where username='+db.raw.escape(name)+' limit 1');
return {"success":key};
@ -60,4 +62,11 @@ async function login(name: string, password: string){
return false;
}
export { register, update, changepwd, changesk, login, updateChat };
async function deleteVODs(vodlist: Array<string>, username: string): Promise<object>{
for(var i=0;i<vodlist.length;i++){
unlink('./site/live/'+username+'/'+vodlist[i], ()=>{});
}
return {"success":""};
}
export { register, update, changepwd, changesk, login, updateChat, deleteVODs };

@ -204,6 +204,25 @@ async function initAPI() {
res.send(result);
});*/
});
app.post('/api/user/vods/delete', (req, res) => {
if(req.body.vlist === undefined || req.body.vlist === null || req.body.vlist === []){
res.send('{"error":"no vods specified"}');
return;
}
validToken(req.cookies.Authorization).then((t) => {
if(t) {
//token is valid, process deletion request
return api.deleteVODs(req.body.vlist, t['username']).then((r)=> {
res.send(r)
return;
});
}
else {
res.send('{"error":"invalid token"}');
return;
}
});
});
app.post('/api/user/password', (req, res) => {
validToken(req.cookies.Authorization).then((t) => {
if(t) {
@ -309,6 +328,23 @@ async function initSite(openReg) {
else res.status(404).render('404.njk', njkconf);
});
});
app.get('/vods/:user/manage', (req, res) => {
db.query('select username from user_meta where username='+db.raw.escape(req.params.user)).then((result) => {
if(result[0]){
readdir('./site/live/'+result[0].username, {withFileTypes: true} , (err, files) => {
if(tryDecode(req.cookies.Authorization)) {
res.render('managevods.njk', Object.assign({user: result[0].username, list: files.filter(fn => fn.name.endsWith('.mp4'))}, {auth: {is: true, name: JWT.decode(req.cookies.Authorization)['username']}}, njkconf));
}
else res.redirect('/login');
//res.render('vods.njk', Object.assign({user: result[0].username, list: files.filter(fn => fn.name.endsWith('.mp4'))}, njkconf));
});
}
else if(tryDecode(req.cookies.Authorization)) {
res.status(404).render('404.njk', Object.assign({auth: {is: true, name: JWT.decode(req.cookies.Authorization)['username']}}, njkconf));
}
else res.status(404).render('404.njk', njkconf);
});
});
app.get('/vods/:user', (req, res) => {
db.query('select username from user_meta where username='+db.raw.escape(req.params.user)).then((result) => {
if(result[0]){

@ -0,0 +1,14 @@
{% extends "base.njk" %}
{% block content %}
<h3>Manage Your VODs</h3>
<form action="/api/user/vods/delete" method="POST" target="responseFrame">
{% asyncEach vid in list%}
<input type="checkbox" id="{{vid.name}}" name="vlist[]" value="{{vid.name}}">
&nbsp<label for="{{vid.name}}">{{vid.name}}</label><p></p>
{% else %}
No recordings found!
{% endeach %}
<input type="submit" value="Delete">
</form>
<iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe>
{% endblock %}

@ -1,6 +1,7 @@
{% extends "base.njk" %}
{% block content %}
<h3>{{ user }}'s VODs</h3>
{% if auth.name == user %}<span style="font-size: small;"><a href="/vods/{{user}}/manage">Manage</a> your vods.</br></span><p></p>{% endif %}
{% asyncEach vid in list%}
<a href="/live/{{ user }}/{{ vid.name }}">{{ vid.name }}</a></br></br>
{% else %}