Merge branch 'client-templates' into 'develop'
Client templates -> develop See merge request knotteye/satyr!27merge-requests/28/merge
commit
9e5b3f360c
|
@ -4,3 +4,4 @@ config/**/*
|
||||||
!config/.gitkeep
|
!config/.gitkeep
|
||||||
install/db_setup.sql
|
install/db_setup.sql
|
||||||
build/**
|
build/**
|
||||||
|
site/templates.js
|
|
@ -15,11 +15,13 @@ Follow the instructions after setup runs.
|
||||||
```bash
|
```bash
|
||||||
npm run start
|
npm run start
|
||||||
```
|
```
|
||||||
You can also run this to skip checking the database version on startup.
|
You can also skip checking the database version and compiling templates (if you don't use server-side rendering) on startup.
|
||||||
```bash
|
```bash
|
||||||
npm run start -- --skip-migrate
|
npm run start -- --skip-migrate --skip-compile
|
||||||
# don't forget to migrate manually when you update
|
# don't forget to migrate manually when you update
|
||||||
npm run migrate
|
npm run migrate
|
||||||
|
# and compile templates after any changes
|
||||||
|
npm run make-templates
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
|
@ -115,7 +115,7 @@ Obtain a signed json web token for authentication
|
||||||
|
|
||||||
**Response**: If succesful, will return `{success: ""}` or `{success: "already verified"}` if the JWT provided is too early to be renewed. If unsuccesful, will return `{error: "invalid password"}` or `{error: "Username or Password Incorrect"}` depending on the authentication method. Note that if a JWT is available, the parameters will be ignored.
|
**Response**: If succesful, will return `{success: ""}` or `{success: "already verified"}` if the JWT provided is too early to be renewed. If unsuccesful, will return `{error: "invalid password"}` or `{error: "Username or Password Incorrect"}` depending on the authentication method. Note that if a JWT is available, the parameters will be ignored.
|
||||||
|
|
||||||
**Notes**: I've already listed nearly every response. My final note is that the JWT is set as the cookie 'Authorization', not returned in the response.
|
**Notes**: The returned JWT is set as the cookie httponly 'Authorization'. It will also return a non httponly cookie X-Auth-As with the username of the authenticated user.
|
||||||
|
|
||||||
|
|
||||||
## /api/user/update
|
## /api/user/update
|
||||||
|
|
|
@ -14,6 +14,7 @@ rtmp:
|
||||||
http:
|
http:
|
||||||
# uncomment to set HSTS when SSL is ready
|
# uncomment to set HSTS when SSL is ready
|
||||||
#hsts: true
|
#hsts: true
|
||||||
|
server_side_render: false
|
||||||
|
|
||||||
database:
|
database:
|
||||||
user: '<dbuser>'
|
user: '<dbuser>'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "satyr",
|
"name": "satyr",
|
||||||
"version": "0.9.3",
|
"version": "0.9.4",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -963,6 +963,11 @@
|
||||||
"asn1.js": "^5.2.0"
|
"asn1.js": "^5.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jwt-decode": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RBQv2MTm3FNKQkdzhEyQwh5MbdNgMa+FyIJIK5RMWEn6hRgRHr7j55cRxGhRe6vGJDElyi6f6u/yfkP7AoXddA=="
|
||||||
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.20",
|
"version": "4.17.20",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "satyr",
|
"name": "satyr",
|
||||||
"version": "0.9.4",
|
"version": "0.10.0",
|
||||||
"description": "A livestreaming server.",
|
"description": "A livestreaming server.",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"author": "knotteye",
|
"author": "knotteye",
|
||||||
|
@ -9,7 +9,8 @@
|
||||||
"cli": "ts-node src/cli.ts",
|
"cli": "ts-node src/cli.ts",
|
||||||
"setup": "sh install/setup.sh",
|
"setup": "sh install/setup.sh",
|
||||||
"migrate": "ts-node src/migrate.ts",
|
"migrate": "ts-node src/migrate.ts",
|
||||||
"invite": "ts-node src/cli.ts --invite"
|
"invite": "ts-node src/cli.ts --invite",
|
||||||
|
"make-templates": "nunjucks-precompile -i [\"\\.html$\",\"\\.njk$\"] templates > site/templates.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/styles.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/local.css">
|
||||||
|
<link rel="icon" type="image/svg" href="/logo.svg">
|
||||||
|
<script src="/nunjucks-slim.js"></script>
|
||||||
|
<script src="/templates.js"></script>
|
||||||
|
<script>
|
||||||
|
nunjucks.configure({ autoescape: true });
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
//should check for and refresh login tokens on pageload..
|
||||||
|
if(document.cookie.match(/^(.*;)?\s*X-Auth-As\s*=\s*[^;]+(.*)?$/) !== null) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "/api/login", true);
|
||||||
|
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
xhr.send("");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="render(window.location.pathname)">
|
||||||
|
<script src="/index.js"></script>
|
||||||
|
</body>
|
|
@ -0,0 +1,170 @@
|
||||||
|
async function render(path){
|
||||||
|
var context = await getContext();
|
||||||
|
switch(path){
|
||||||
|
//nothing but context
|
||||||
|
case (path.match(/^\/about\/?$/) || {}).input:
|
||||||
|
document.body.innerHTML = nunjucks.render('about.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/login\/?$/) || {}).input:
|
||||||
|
document.body.innerHTML = nunjucks.render('login.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/register\/?$/) || {}).input:
|
||||||
|
if(!context.registration) window.location = '/';
|
||||||
|
document.body.innerHTML = nunjucks.render('registration.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/changepwd\/?$/) || {}).input:
|
||||||
|
document.body.innerHTML = nunjucks.render('changepwd.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/chat\/?$/) || {}).input:
|
||||||
|
document.body.innerHTML = nunjucks.render('chat.html', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/help\/?$/) || {}).input:
|
||||||
|
document.body.innerHTML = nunjucks.render('help.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
//need to hit the API
|
||||||
|
case (path.match(/^\/users\/live\/?$/) || {}).input:
|
||||||
|
var list = JSON.parse(await makeRequest("POST", "/api/users/live", JSON.stringify({num: 50})));
|
||||||
|
document.body.innerHTML = nunjucks.render('live.njk', Object.assign({list: list.users}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/users\/?$/) || {}).input:
|
||||||
|
var list = JSON.parse(await makeRequest("POST", "/api/users/all", JSON.stringify({num: 50})));
|
||||||
|
document.body.innerHTML = nunjucks.render('list.njk', Object.assign({list: list.users}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/profile\/chat\/?$/) || {}).input:
|
||||||
|
if(!context.auth.name) window.location = '/login';
|
||||||
|
var config = JSON.parse(await makeRequest("GET", '/api/'+context.auth.name+'/config'));
|
||||||
|
config = {
|
||||||
|
integ: {
|
||||||
|
twitch: config.twitch,
|
||||||
|
xmpp: config.xmpp,
|
||||||
|
irc: config.irc,
|
||||||
|
discord: config.discord
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.body.innerHTML = nunjucks.render('chat_integ.njk', Object.assign(config, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/profile\/?$/) || {}).input:
|
||||||
|
if(!context.auth.name) window.location = '/login';
|
||||||
|
var config = JSON.parse(await makeRequest("GET", '/api/'+context.auth.name+'/config'));
|
||||||
|
config = {
|
||||||
|
meta: {
|
||||||
|
title: config.title,
|
||||||
|
about: config.about
|
||||||
|
},
|
||||||
|
rflag: {record_flag: config.record_flag},
|
||||||
|
twitch: config.twitch_mirror
|
||||||
|
};
|
||||||
|
document.body.innerHTML = nunjucks.render('profile.njk', Object.assign(config, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
//parsing slugs
|
||||||
|
case (path.match(/^\/invite\//) || {}).input: // /invite/:code
|
||||||
|
document.body.innerHTML = nunjucks.render('invite.njk', Object.assign({icode: path.substring(8)}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
//slugs and API
|
||||||
|
case (path.match(/^\/users\/.+\/?$/) || {}).input: // /users/:user
|
||||||
|
if(path.substring(path.length - 1).indexOf('/') !== -1)
|
||||||
|
var usr = path.substring(7, path.length - 1);
|
||||||
|
else var usr = path.substring(7);
|
||||||
|
var config = JSON.parse(await makeRequest("GET", '/api/'+usr+'/config'));
|
||||||
|
if(!config.title){document.body.innerHTML = nunjucks.render('404.njk', context); break;}
|
||||||
|
document.body.innerHTML = nunjucks.render('user.njk', Object.assign({about: config.about, title: config.title, username: config.username}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/vods\/.+\/manage\/?$/) || {}).input: // /vods/:user/manage
|
||||||
|
var usr = path.substring(6, (path.length - 7));
|
||||||
|
if(context.auth.name !== usr) window.location = '/vods/'+usr;
|
||||||
|
var vods = JSON.parse(await makeRequest("GET", '/api/'+usr+'/vods'));
|
||||||
|
document.body.innerHTML = nunjucks.render('managevods.njk', Object.assign({user: usr, list: vods.vods.filter(fn => fn.name.endsWith('.mp4'))}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
case (path.match(/^\/vods\/.+\/?$/) || {}).input: // /vods/:user
|
||||||
|
if(path.substring(path.length - 1).indexOf('/') !== -1)
|
||||||
|
var usr = path.substring(6, path.length - 1);
|
||||||
|
else var usr = path.substring(6);
|
||||||
|
var vods = JSON.parse(await makeRequest("GET", '/api/'+usr+'/vods'));
|
||||||
|
document.body.innerHTML = nunjucks.render('vods.njk', Object.assign({user: usr, list: vods.vods.filter(fn => fn.name.endsWith('.mp4'))}, context));
|
||||||
|
modifyLinks();
|
||||||
|
break;
|
||||||
|
//root
|
||||||
|
case "/":
|
||||||
|
render('/users/live');
|
||||||
|
break;
|
||||||
|
case "":
|
||||||
|
render('/users/live');
|
||||||
|
break;
|
||||||
|
//404
|
||||||
|
default:
|
||||||
|
document.body.innerHTML = nunjucks.render('404.njk', context);
|
||||||
|
modifyLinks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getContext(){
|
||||||
|
var info = JSON.parse(await makeRequest('GET', '/api/instance/info'));
|
||||||
|
info.sitename = info.name;
|
||||||
|
info.name = null;
|
||||||
|
info.auth = {
|
||||||
|
is: document.cookie.match(/^(.*;)?\s*X-Auth-As\s*=\s*[^;]+(.*)?$/) !== null,
|
||||||
|
name: parseCookie(document.cookie)['X-Auth-As']
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeRequest(method, url, payload) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open(method, url);
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (this.status >= 200 && this.status < 300) {
|
||||||
|
resolve(xhr.response);
|
||||||
|
} else {
|
||||||
|
reject({
|
||||||
|
status: this.status,
|
||||||
|
statusText: xhr.statusText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onerror = function () {
|
||||||
|
reject({
|
||||||
|
status: this.status,
|
||||||
|
statusText: xhr.statusText
|
||||||
|
});
|
||||||
|
};
|
||||||
|
!payload ? xhr.send() : xhr.send(payload);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCookie(c){
|
||||||
|
if(typeof(c) !== 'string' || !c.includes('=')) return {};
|
||||||
|
return Object.assign({[c.split('=')[0].trim()]:c.split('=')[1].split(';')[0].trim()}, parseCookie(c.split(/;(.+)/)[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLoad() {
|
||||||
|
var r = JSON.parse(document.getElementById('responseFrame').contentDocument.documentElement.textContent).success
|
||||||
|
if (typeof(r) !== 'undefined') window.location.href = '/profile'
|
||||||
|
}
|
||||||
|
|
||||||
|
function modifyLinks() {
|
||||||
|
for (var ls = document.links, numLinks = ls.length, i=0; i<numLinks; i++){
|
||||||
|
if(ls[i].href.indexOf(location.protocol+'//'+location.host) !== -1) {
|
||||||
|
//should be a regular link
|
||||||
|
ls[i].setAttribute('onclick', 'return internalLink(\"'+ls[i].href.substring((location.protocol+'//'+location.host).length)+'\")');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function internalLink(path){
|
||||||
|
this.render(path);
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -87,9 +87,11 @@ async function getConfig(username: string, all?: boolean): Promise<object>{
|
||||||
let users = await db.query('SELECT stream_key,record_flag FROM users WHERE username='+db.raw.escape(username));
|
let users = await db.query('SELECT stream_key,record_flag FROM users WHERE username='+db.raw.escape(username));
|
||||||
if(users[0]) Object.assign(t, users[0]);
|
if(users[0]) Object.assign(t, users[0]);
|
||||||
let usermeta = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
let usermeta = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
||||||
if(usermeta[0]) Object.assign(t, users[0]);
|
if(usermeta[0]) Object.assign(t, usermeta[0]);
|
||||||
let ci = await db.query('SELECT irc,xmpp,twitch,discord FROM chat_integration WHERE username='+db.raw.escape(username));
|
let ci = await db.query('SELECT irc,xmpp,twitch,discord FROM chat_integration WHERE username='+db.raw.escape(username));
|
||||||
if(ci[0]) Object.assign(t, ci[0]);
|
if(ci[0]) Object.assign(t, ci[0]);
|
||||||
|
let tw = await db.query('SELECT enabled,twitch_key FROM twitch_mirror WHERE username='+db.raw.escape(username));
|
||||||
|
if(tw[0]) t['twitch_mirror'] = Object.assign({}, tw[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let um = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
let um = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import * as db from "./database";
|
import * as db from "./database";
|
||||||
import {readdirSync} from "fs";
|
import {readdirSync} from "fs";
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
|
||||||
async function init(m?: boolean) {
|
async function init() {
|
||||||
if(!m){
|
if(process.argv.indexOf('--skip-migrate') === -1){
|
||||||
console.log('Checking database version.');
|
console.log('Checking database version.');
|
||||||
var tmp: string[] = await db.query('show tables like \"db_meta\"');
|
var tmp: string[] = await db.query('show tables like \"db_meta\"');
|
||||||
if(tmp.length === 0){
|
if(tmp.length === 0){
|
||||||
|
@ -17,6 +18,15 @@ async function init(m?: boolean) {
|
||||||
else {
|
else {
|
||||||
console.log('Skipping database version check.');
|
console.log('Skipping database version check.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!require('./config').config['http']['server_side_render'] && process.argv.indexOf('--skip-compile') === -1) {
|
||||||
|
console.log("Compiling templates for client-side frontend.");
|
||||||
|
execSync(process.cwd()+'/node_modules/.bin/nunjucks-precompile -i [\"\\.html$\",\"\\.njk$\"] templates > site/templates.js');
|
||||||
|
}
|
||||||
|
else if(!require('./config').config['http']['server_side_render']){
|
||||||
|
console.log("Skipped compiling templates for client-side frontend.");
|
||||||
|
}
|
||||||
|
|
||||||
//If satyr is restarted in the middle of a stream
|
//If satyr is restarted in the middle of a stream
|
||||||
//it causes problems
|
//it causes problems
|
||||||
//Live flags in the database stay live
|
//Live flags in the database stay live
|
||||||
|
|
|
@ -36,7 +36,10 @@ const config: Object = {
|
||||||
ping: 30,
|
ping: 30,
|
||||||
ping_timeout: 60 }, localconfig['rtmp']),
|
ping_timeout: 60 }, localconfig['rtmp']),
|
||||||
http: Object.assign({
|
http: Object.assign({
|
||||||
hsts: false, directory: './site', port: 8000
|
hsts: false,
|
||||||
|
directory: './site',
|
||||||
|
port: 8000,
|
||||||
|
server_side_render: true
|
||||||
}, localconfig['http']),
|
}, localconfig['http']),
|
||||||
media: Object.assign({
|
media: Object.assign({
|
||||||
record: false,
|
record: false,
|
||||||
|
|
30
src/http.ts
30
src/http.ts
|
@ -12,9 +12,6 @@ import * as chatInteg from "./chat";
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
import { readdir, readFileSync, writeFileSync } from "fs";
|
import { readdir, readFileSync, writeFileSync } from "fs";
|
||||||
import { JWT, JWK } from "jose";
|
import { JWT, JWK } from "jose";
|
||||||
import { strict } from "assert";
|
|
||||||
import { parse } from "path";
|
|
||||||
import { isBuffer } from "util";
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
@ -55,12 +52,16 @@ async function init(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
app.disable('x-powered-by');
|
app.disable('x-powered-by');
|
||||||
//site handlers
|
//server-side site routes
|
||||||
|
if(config['http']['server_side_render'])
|
||||||
await initSite(config['satyr']['registration']);
|
await initSite(config['satyr']['registration']);
|
||||||
//api handlers
|
//api routes
|
||||||
await initAPI();
|
await initAPI();
|
||||||
//static files if nothing else matches first
|
//static files if nothing else matches
|
||||||
app.use(express.static(config['http']['directory']));
|
app.use(express.static(config['http']['directory']));
|
||||||
|
//client-side site routes
|
||||||
|
if(!config['http']['server_side_render'])
|
||||||
|
await initFE();
|
||||||
//404 Handler
|
//404 Handler
|
||||||
app.use(function (req, res, next) {
|
app.use(function (req, res, next) {
|
||||||
if(tryDecode(req.cookies.Authorization)) {
|
if(tryDecode(req.cookies.Authorization)) {
|
||||||
|
@ -73,6 +74,21 @@ async function init(){
|
||||||
server.listen(config['http']['port']);
|
server.listen(config['http']['port']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function initFE(){
|
||||||
|
app.get('/', (req, res) => {
|
||||||
|
res.redirect(config['satyr']['rootredirect']);
|
||||||
|
});
|
||||||
|
app.get('/nunjucks-slim.js', (req, res) => {
|
||||||
|
res.sendFile(process.cwd()+'/node_modules/nunjucks/browser/nunjucks-slim.js');
|
||||||
|
});
|
||||||
|
app.get('/chat', (req, res) => {
|
||||||
|
res.sendFile(process.cwd()+'/templates/chat.html');
|
||||||
|
});
|
||||||
|
app.get('*', (req, res) => {
|
||||||
|
res.sendFile(process.cwd()+'/'+config['http']['directory']+'/index.html');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function newNick(socket, skip?: boolean, i?: number) {
|
async function newNick(socket, skip?: boolean, i?: number) {
|
||||||
if(socket.handshake.headers['cookie'] && !skip){
|
if(socket.handshake.headers['cookie'] && !skip){
|
||||||
let c = await parseCookie(socket.handshake.headers['cookie']);
|
let c = await parseCookie(socket.handshake.headers['cookie']);
|
||||||
|
@ -361,6 +377,7 @@ async function initAPI() {
|
||||||
if(req.cookies.Authorization) validToken(req.cookies.Authorization).then((t) => {
|
if(req.cookies.Authorization) validToken(req.cookies.Authorization).then((t) => {
|
||||||
if(t) {
|
if(t) {
|
||||||
if(t['exp'] - 86400 < Math.floor(Date.now() / 1000)){
|
if(t['exp'] - 86400 < Math.floor(Date.now() / 1000)){
|
||||||
|
res.cookie('X-Auth-As', t['username'], {maxAge: 604800000, httpOnly: false, sameSite: 'Lax'});
|
||||||
return genToken(t['username']).then((t) => {
|
return genToken(t['username']).then((t) => {
|
||||||
res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'});
|
res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'});
|
||||||
res.json({success:""});
|
res.json({success:""});
|
||||||
|
@ -382,6 +399,7 @@ async function initAPI() {
|
||||||
if(!result){
|
if(!result){
|
||||||
genToken(req.body.username).then((t) => {
|
genToken(req.body.username).then((t) => {
|
||||||
res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'});
|
res.cookie('Authorization', t, {maxAge: 604800000, httpOnly: true, sameSite: 'Lax'});
|
||||||
|
res.cookie('X-Auth-As', req.body.username, {maxAge: 604800000, httpOnly: false, sameSite: 'Lax'});
|
||||||
res.json({success:""});
|
res.json({success:""});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { config } from "./config";
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
await initDB();
|
await initDB();
|
||||||
await clean(process.argv.indexOf('--skip-migrate') !== -1);
|
await clean();
|
||||||
await initHTTP();
|
await initHTTP();
|
||||||
await initRTMP();
|
await initRTMP();
|
||||||
await initChat();
|
await initChat();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<title>{{ sitename }}</title>
|
<title>{{ sitename }}</title>
|
||||||
<script>
|
<script>
|
||||||
//should check for and refresh login tokens on pageload..
|
//should check for and refresh login tokens on pageload..
|
||||||
if(document.cookie.match(/^(.*;)?\s*Authorization\s*=\s*[^;]+(.*)?$/) !== null) {
|
if(document.cookie.match(/^(.*;)?\s*X-Auth-As\s*=\s*[^;]+(.*)?$/) !== null) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST", "/api/login", true);
|
xhr.open("POST", "/api/login", true);
|
||||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
No recordings found!
|
No recordings found!
|
||||||
{% endeach %}
|
{% endeach %}
|
||||||
<input type="submit" value="Delete">
|
</br><input type="submit" value="Delete">
|
||||||
</form>
|
</form>
|
||||||
<iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe>
|
<iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe>
|
||||||
{% endblock %}
|
{% endblock %}
|
Reference in New Issue