no longer store stream key in DOM on dashboard

This commit is contained in:
Evert Prants 2021-02-14 09:54:09 +02:00
parent 1ab2c3df17
commit b0ed4f0e7a
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
10 changed files with 93 additions and 71 deletions

12
app.js
View File

@ -75,7 +75,7 @@ config = Object.assign({
}, config)
// Constants
const port = parseInt(config.Streaming.port)
const port = parseInt(config.Streaming.port, 10)
const streamServer = config.Streaming.streamServer
const streamServerHost = config.Streaming.serverHost
const streamAppName = streamServer.match(/\/([\w-_]+)\/$/)[1]
@ -426,7 +426,7 @@ app.get('/', (req, res) => {
// Dashboard
app.get('/dashboard', authed, (req, res) => {
const stream = cache.streamers[req.user.uuid]
res.render('dashboard.html', { stream: stream.key, server: 'rtmp://' + streamServerHost + '/live/' })
res.render('dashboard.html', { server: 'rtmp://' + streamServerHost + '/live/' })
})
// Stats
@ -464,8 +464,8 @@ app.get('/dashboard/data', authed, async (req, res) => {
key: stream.key,
uuid: req.user.uuid,
live: data.live_at != null,
live_at: new Date(parseInt(data.live_at)),
last_stream: new Date(parseInt(data.last_stream))
live_at: new Date(parseInt(data.live_at, 10)),
last_stream: new Date(parseInt(data.last_stream, 10))
})
})
@ -552,8 +552,8 @@ app.get('/api/channel/:name', async (req, res) => {
delete data.user_uuid
data.live = data.live_at != null
data.live_at = new Date(parseInt(data.live_at))
data.last_stream = new Date(parseInt(data.last_stream))
data.live_at = new Date(parseInt(data.live_at, 10))
data.last_stream = new Date(parseInt(data.last_stream, 10))
data.links = links || []
data.viewers = Object.keys(cache.viewers[name] || {}).length
data.source = streamServer + name + '.m3u8'

View File

@ -6,7 +6,7 @@
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack -w --mode=development --log-level=debug",
"watch": "webpack -w --mode=development",
"build": "webpack --mode=production",
"start": "node app.js",
"serve": "NODE_ENV=\"development\" node app.js"

View File

@ -66,6 +66,10 @@ body {
width: 40px;
cursor: pointer;
padding: 4px;
text-align: center;
}
.controls .button:hover {
background-color: #005193;
}
.flex-divider {
flex-grow: 1;

View File

@ -51,13 +51,18 @@ function updateLinkList (k) {
})
}
function dashboard (k) {
function dashboard () {
let key;
let shown = false;
$.get('/dashboard/data', function (res) {
if (res.error) {
window.location.href = '/'
return
}
// Set key from request
key = res.key
const fullURL = window.location.origin + '/watch/' + res.name
const sourceURL = window.location.origin + '/live/' + res.name + '.m3u8'
$('#myStream').attr('src', fullURL)
@ -66,12 +71,33 @@ function dashboard (k) {
$('#stream_live').text(res.live ? 'Yes' : 'No')
})
$('#show_key').click(function (e) {
e.preventDefault()
$('#show_key').html(k)
$('#keybox').val('A'.repeat(36))
$('#show_key').on('click', function (e) {
if (shown) {
$('#keybox').val('A'.repeat(36))
$('#keybox').attr('type', 'password')
$(this).text('Reveal Key')
} else {
$('#keybox').val(key)
$('#keybox').attr('type', 'text')
$(this).text('Hide Key')
}
shown = !shown
})
$('.go-page').click(function (e) {
$('#copy_key').on('click', function (e) {
const i = $('<input>').attr('value', key)
$(this).append(i)
$(this).attr('title', 'Click to copy to clipboard')
i[0].select()
i[0].setSelectionRange(0, key.length)
document.execCommand('copy')
$(i).remove()
$(this).text('Copied!')
setTimeout(() => $(this).text('Copy'), 1000)
})
$('.go-page').on('click', function (e) {
const el = $(this)
$('.go-page').removeClass('active')
el.addClass('active')
@ -80,7 +106,7 @@ function dashboard (k) {
})
})
$('#add-link').submit(function (e) {
$('#add-link').on('submit', function (e) {
e.preventDefault()
const name = $('input[name="name"]').val()
const url = $('input[name="url"]').val()

View File

@ -1,5 +1,6 @@
/* global STREAM_KEY */
import 'bootstrap'
import dashboard from './dashboard.js'
if (window.STREAM_KEY) dashboard(window.STREAM_KEY)
if (window.location.pathname.startsWith('/dashboard')) dashboard()

View File

@ -32,26 +32,6 @@ let errored = false
let live = false
let ws
function GET (url, istext) {
return new Promise((resolve, reject) => {
var xmlHttp = new XMLHttpRequest()
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
resolve(xmlHttp.responseText)
} else if (xmlHttp.readyState === 4 && xmlHttp.status >= 400) {
const err = new Error(xmlHttp.status)
err.request = xmlHttp
reject(err)
}
}
xmlHttp.open('GET', url, true)
istext && (xmlHttp.responseType = 'text')
xmlHttp.send(null)
})
}
function clampAddition (val) {
let volume = vid.volume
@ -391,6 +371,7 @@ function updateLinks (srcs) {
if (!links) {
links = document.createElement('div')
links.className = 'right button'
links.setAttribute('title', 'Links')
links.id = 'links'
links.innerHTML = '<i class="fa fa-link" aria-hidden="true"></i>'
overlay.getElementsByClassName('controls')[0].insertBefore(links, fullscreenbtn)
@ -431,22 +412,23 @@ function updateLinks (srcs) {
}
function getStreamStatus () {
GET('/api/channel/' + STREAM_NAME).then((data) => {
const jd = JSON.parse(data)
if (jd.error) {
fetch('/api/channel/' + STREAM_NAME)
.then(data => data.json())
.then((jd) => {
if (jd.error) {
errored = true
return alert(jd.error)
}
if (jd.links) updateLinks(jd.links)
if (ws) ws.send('viewers ' + STREAM_NAME)
if (jd.live && !vidReady) loadSource()
liveStatus(jd.live)
}, (e) => {
errored = true
return alert(jd.error)
}
if (jd.links) updateLinks(jd.links)
if (ws) ws.send('viewers ' + STREAM_NAME)
if (jd.live && !vidReady) loadSource()
liveStatus(jd.live)
}, (e) => {
errored = true
liveStatus(false)
})
liveStatus(false)
})
if (!errored) setTimeout(getStreamStatus, 8000)
}

View File

@ -1,9 +1,6 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<script type="text/javascript">
window.STREAM_KEY = "{{ stream }}"
</script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/dist/css/dashboard.css">
@ -47,6 +44,7 @@
</div>
<iframe allowfullscreen src="" id="myStream" width="1542" height="651" style="display: block; width: 1542px; height: 651px;"></iframe>
<br>
<h1 class="h2">Information</h1>
<p class="lead">
<div class="row">
@ -67,15 +65,6 @@
</div>
</div>
<div class="row">
<div class="col-2">
<label>Stream Key</label>
</div>
<div class="col">
<a href="#" id="show_key">Show Stream Key</a>
</div>
</div>
<div class="row">
<div class="col-2">
<label>Stream URL</label>
@ -93,6 +82,17 @@
<a href="" id="source_url"></a>
</div>
</div>
<div class="row">
<div class="col-2">
<label>Stream Key</label>
</div>
<div class="col">
<input type="password" id="keybox">
<button href="#" id="show_key" class="btn btn-primary">Reveal Key</button>
<button href="#" id="copy_key" class="btn btn-success">Copy</button>
</div>
</div>
</p>
<h1 class="h2">Metrics</h1>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/dist/css/bootstrap.min.css">

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>IcyTV - {{ name }}</title>
@ -20,19 +20,27 @@
<div class="overlay">
<div class="badge live offline">offline</div>
<div class="badge viewers" style="display: none;">0</div>
<div class="bigplaybtn hidden"><i class="fa fa-play fa-fw"></i></div>
<div class="bigplaybtn hidden" title="Play">
<i class="fa fa-play fa-fw" aria-hidden="true"></i>
</div>
<div class="controls">
<div id="playbtn" class="button"><i class="fa fa-play fa-fw"></i></div>
<span class="seekview" id="volume_seek">
<div id="mutebtn" class="button"><i class="fa fa-volume-up fa-fw"></i></div>
<div class="seeker">
<div id="mutebtn" class="button" title="Mute">
<i class="fa fa-volume-up fa-fw" aria-hidden="true"></i>
</div>
<div class="seeker" aria-hidden="true">
<div class="seekbar" style="width: 100%"></div>
</div>
</span>
<div id="duration">0:00</div>
<div class="flex-divider"></div>
<div id="subbtn" class="right button" title="Subscribe"><i class="fa fa-envelope-o fa-fw"></i></div>
<div id="fullscrbtn" class="right button" title="Fullscreen"><i class="fa fa-expand fa-fw"></i></div>
<div id="subbtn" class="right button" title="Subscribe">
<i class="fa fa-envelope-o fa-fw" aria-hidden="true"></i>
</div>
<div id="fullscrbtn" class="right button" title="Fullscreen">
<i class="fa fa-expand fa-fw" aria-hidden="true"></i>
</div>
</div>
</div>
</div>

View File

@ -16,8 +16,9 @@ module.exports = {
plugins: [
new CopyPlugin({
patterns: [{
from: 'src/css/*.css',
to: 'css'
from: '*',
to: 'css',
context: 'src/css/'
},
{
from: 'node_modules/bootstrap/dist/css/bootstrap.min.css',