From f9e4a7a5c6caa04d62d34c978df418c1ca2ee5dd Mon Sep 17 00:00:00 2001 From: knotteye <knotteye@airmail.cc> Date: Sat, 5 Oct 2019 14:34:57 -0500 Subject: [PATCH] I don't even know. Filled out API for user management Proper escaping of user input for SQL queries (stream keys aren't user input) Filled out frontend with profile management, vods, etc. I don't remember there's probably more, fuck. --- config/default.toml | 4 +- install/db_template.sql | 7 ++- install/setup.sh | 6 ++- install/template.local.toml | 2 +- site/logo.svg | 78 +++++++++++++++++++++++++++ site/styles.css | 10 ++-- src/api.ts | 55 +++++++++++-------- src/cli.ts | 20 +------ src/controller.ts | 5 +- src/database.ts | 42 ++++++--------- src/http.ts | 92 +++++++++++++++++++++++++++----- src/server.ts | 17 +++++- templates/{index.njk => 404.njk} | 3 +- templates/about.html | 2 +- templates/base.njk | 8 +-- templates/changepwd.njk | 12 +++++ templates/changesk.njk | 11 ++++ templates/list.njk | 9 ++++ templates/live.njk | 9 ++++ templates/login.njk | 0 templates/profile.njk | 14 +++++ templates/registration.njk | 5 +- templates/tos.html | 2 +- templates/user.njk | 5 +- templates/vods.njk | 9 ++++ 25 files changed, 323 insertions(+), 104 deletions(-) create mode 100644 site/logo.svg rename templates/{index.njk => 404.njk} (64%) create mode 100644 templates/changepwd.njk create mode 100644 templates/changesk.njk create mode 100644 templates/list.njk create mode 100644 templates/live.njk delete mode 100644 templates/login.njk create mode 100644 templates/vods.njk diff --git a/config/default.toml b/config/default.toml index 9af96b5..250df3f 100644 --- a/config/default.toml +++ b/config/default.toml @@ -8,7 +8,8 @@ name = '' domain = '' registration = false webFormat = 'hls' -restrictedNames = ['live','stream'] +restrictedNames = ['live'] +rootredirect = '/users/live' [ircd] enable = false @@ -45,7 +46,6 @@ allow_origin = '*' directory = './site' [media] -streamKeys = false record = false publicEndpoint = 'live' privateEndpoint = 'stream' diff --git a/install/db_template.sql b/install/db_template.sql index 4393693..97c0f6d 100644 --- a/install/db_template.sql +++ b/install/db_template.sql @@ -7,5 +7,10 @@ CREATE TABLE users( password_hash BINARY(60), stream_key CHAR(20), record_flag TINYINT, - is_mod TINYINT +); +CREATE TABLE user_meta( + username VARCHAR(25), + title VARCHAR(120), + about VARCHAR(5000), + live TINYINT ); \ No newline at end of file diff --git a/install/setup.sh b/install/setup.sh index 58a64b4..6741d48 100644 --- a/install/setup.sh +++ b/install/setup.sh @@ -13,6 +13,8 @@ do echo "Please the domain name for your instance.[]" read domain done +echo "Enter the contact email for the instance." +read email echo "Please enter the path to the ffmpeg binary on your system.[$(which ffmpeg)]" read ffmpeg ffmpeg="${ffmpeg:=$(which ffmpeg)}" @@ -30,13 +32,13 @@ read dbhost dbhost="${dbhost:=localhost}" if [ "$dbhost" != "localhost" ] then -echo "Please enter the ip this server will connect to the database with.[*]" +echo "Please enter the public ip or hostname this server will connect to the database with.[*]" read dbclient dbclient="${dbclient:='*'}" else dbclient="localhost" fi -sed -e "s#<iname>#$name#g" -e "s#<domain>#$domain#g" -e "s#<ffmpeg>#$ffmpeg#g" -e "s#<dbuser>#$dbuser#g" -e "s#<dbname>#$dbname#g" -e "s#<dbpass>#$dbpass#g" -e "s#<dbhost>#$dbhost#g" install/template.local.toml > config/generated.toml +sed -e "s#<iname>#$name#g" -e "s#<domain>#$domain#g" -e "s#<ffmpeg>#$ffmpeg#g" -e "s#<dbuser>#$dbuser#g" -e "s#<dbname>#$dbname#g" -e "s#<dbpass>#$dbpass#g" -e "s#<dbhost>#$dbhost#g" -e "s#<email>#$email#g" install/template.local.toml > config/generated.toml sed -e "s#<dbuser>#$dbuser#g" -e "s#<dbname>#$dbname#g" -e "s#<dbpass>#$dbpass#g" -e "s#<dbhost>#$dbhost#g" -e "s#<dbclient>#$dbclient#g" install/db_template.sql > install/db_setup.sql echo "A setup script for the database has been generated at install/db_setup.sql. Please run it by connecting to your database software and executing 'source install/db_setup.sql;''" echo "A default configuration file has been generated at config/generated.toml" diff --git a/install/template.local.toml b/install/template.local.toml index d3bc491..92d6d27 100644 --- a/install/template.local.toml +++ b/install/template.local.toml @@ -1,10 +1,10 @@ [satyr] name = '<iname>' domain = '<domain>' +email = '<email>' registration = false [media] -streamKeys = false record = false ffmpeg = '<ffmpeg>' diff --git a/site/logo.svg b/site/logo.svg new file mode 100644 index 0000000..5ed78f3 --- /dev/null +++ b/site/logo.svg @@ -0,0 +1,78 @@ +<?xml version="1.0"?> +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" id="fife_xA0_Image_1_" xml:space="preserve" viewBox="-111.032 -46.682 321.472 283.564" version="1.1" x="0px" y="0px" enable-background="new -111.032 -46.682 321.472 283.564"> + <path d="m155.67-37.952c-5.231 6.267-24.74 4.75-32.224 1.611 5.56-7.555 24.68-6.525 32.22-1.611zm-22.56 0.806c3.974 1.07 14.413 2.217 16.113-1.609-7.09 0.682-12.45-2.785-16.11 1.609z" fill="#fff"/> + <path d="m195.14-36.341c-2.6 1.162-6.759 0.762-10.477 0.805v-4.027h-12.888c0.046 3.984 7.746 0.312 8.054 4.027-6.107-0.065-12.688 0.339-16.111-2.416 5.75-6.895 26.65-4.586 31.43 1.611z" fill="#fff"/> + <path d="m-82.778-40.368c4.669 1.775 13.573-0.688 16.11 3.222-6.816 4.873-22.413 3.147-28.999-0.806 5.384-3.125 14.301 3.877 24.166 1.611-0.826-4.276-11.636 1.434-11.277-4.027z" fill="#fff"/> + <path d="m3.415-36.341c-5.877 3.93-24.39 3.347-31.416 0.805 5.411-6.736 24.669-5.846 31.416-0.805zm-11.278 0c6.027-0.385 3.923-0.477-1.611-0.805-3.873-0.229-6.028-1.129-9.667 0.805 4.882-0.118 8.703 0.163 11.278 0z" fill="#fff"/> + <path d="m79.135-34.73c-10.325 3.346-22.793 2.555-33.83 0 5.519-8.16 27.184-6.887 33.83 0zm-24.971-0.807c5.646-0.529 13.421 1.065 17.721-0.805-4.903-0.996-13.963-1.748-17.721 0.805z" fill="#fff"/> + <path d="m117-37.146c-6.592 4.504-25.177 7.36-32.224 1.609 4.705-6.848 25.514-6.296 32.224-1.609zm-26.586 0.805c4.541 1.131 14.092 0.81 17.725-1.611-5.91 0.537-14.255-1.364-17.726 1.611z" fill="#fff"/> + <path d="m41.276-36.341c-6.116 5.196-25.757 7.405-33.027 1.611 6.963-7.585 23.659-4.958 33.027-1.611zm-7.251 0.804c-4.663-1.254-14.69-1.403-19.332 0 4.724 0.615 13.264 1.672 19.332 0z" fill="#fff"/> + <path d="m149.22-38.759c-1.7 3.83-12.14 2.683-16.113 1.61 3.66-4.391 9.02-0.924 16.11-1.61z"/> + <path d="m-32.835-35.537c-5.256 4.797-23.3 2.689-29 0 5.72-5.52 22.724-3.504 29 0zm-11.277 0.807h5.638c-4.523-1.564-6.38-1.083-11.278-1.611 0.478 3.738 3.975-0.215 5.64 1.611z" fill="#fff"/> + <path d="m-19.14-36.341c3.639-1.934 5.793-1.038 9.667-0.805 5.534 0.331 7.638 0.419 1.611 0.805-2.576 0.163-6.397-0.118-11.278 0z"/> + <path d="m108.14-37.952c-3.633 2.421-13.184 2.742-17.725 1.611 3.47-2.975 11.815-1.074 17.725-1.611z"/> + <path d="m71.884-36.341c-4.3 1.87-12.074 0.275-17.721 0.805 3.759-2.554 12.819-1.802 17.721-0.805z"/> + <path d="m14.693-35.537c4.642-1.403 14.669-1.254 19.332 0-6.068 1.672-14.608 0.615-19.332 0z"/> + <path d="m160.5-35.537c9.24 4.864 27.5 0.944 37.056 1.612 2.549 17.809-0.805 40.288 0.803 57.194-10.791 1.335-27.071 1.335-37.858 0-1.46-18.603-1.15-42.174 0-58.806zm6.44 33.029c-6.007 9.176 0.349 24.895 14.502 21.75 5.746-3.373 12.422-12.616 8.05-20.945-5.98-1.802-15.24-0.322-22.55-0.805z" fill="#fff"/> + <path d="m-98.084-34.73c9.25 1.662 16.537 4.239 27.39 2.417 1.842 17.487 0.295 38.37 0.804 57.192-7.783 1.616-18.335 0.457-27.388 0.806-2.882-18.735-1.027-40.26-0.806-60.415zm4.029 34.639c-2.588 20.034 24.421 23.554 22.555 0.804-7.838-2.456-15.198-2.695-22.555-0.804z" fill="#fff"/> + <path d="m-65.861-33.924c6.995 4.252 22.921 3.06 31.416 3.223-0.526 18.806 1.06 39.727-0.806 57.194-9.523-1.22-20.844-0.639-30.61-1.613 0.25-19.598-2.277-38.546 0-58.804zm11.277 51.555c12.228 4.01 20.408-6.059 16.916-17.722-5.719-1.799-14.707-0.33-21.75-0.806-1.073 5.772 0.722 15.288 4.834 18.528z" fill="#fff"/> + <path d="m154.86-33.924h1.606c-0.741 21.376 0.163 35.205-1.606 57.999h-31.417c-2.662-18.434-1.597-41.267-0.807-57.194 11.13 1.171 22.47 2.216 32.23-0.805zm-28.2 31.416c-3.625 29.265 30.511 22.387 24.971 0.805-6.57-1.57-19.69-0.6-24.97-0.805z" fill="#fff"/> + <path d="m117.8-33.12c1.561 21.344-0.039 36.579 0 57.194-15.91-0.721-24.74 1.954-35.446-0.805-0.249-21.311-1.314-36.401 0.807-55.583 10.004 3.694 23.879 1.343 34.639-0.806zm-26.582 31.416c-2.53 6.71 0.53 14.399 4.025 17.723 12.518 3.856 20.117-3.27 18.531-16.11-9.89-2.129-14.085-0.844-22.552-1.613z" fill="#fff"/> + <path d="m2.609-32.313c0.816 16.782 0.107 41.998-0.805 57.192-11.031-0.292-21.271 0.213-31.416 0.806-1.08-19.235-1.615-41.213-0.805-57.999 11.623 2.038 21.9 0.662 33.026 0.001zm-25.777 32.222c1.613 5.141 0.649 9.017 1.61 13.693 8.727 12.01 28.752-2.249 20.139-14.499-5.997 1.973-15.248-1.836-21.749 0.806z" fill="#fff"/> + <path d="m6.638-31.508c9.206 4.981 24.508 1.426 34.638 0 1.102 16.984 1.399 37.029 0 56.388h-34.638c-2.008-17.926-0.128-42.707 0-56.388zm8.861 32.221c-0.543 7.258 0.421 13.006 4.028 16.111 12.942 4.615 21.644-5.471 18.528-16.915-8.133 0.171-15.605-2.528-22.556 0.804z" fill="#fff"/> + <path d="m76.719-31.508c4.046 13.211 0.346 38.062 1.61 56.388h-32.224c-0.669-14.82-1.717-35.73 0-55.581 10.617 0.878 20.352 0.471 30.614-0.807zm-24.97 32.221c-3.844 22.079 27.584 20.958 24.165 0-8.886-1.251-17.271-2.494-24.165 0z" fill="#fff"/> + <path d="m151.63-1.704c5.537 21.586-28.599 28.46-24.971-0.805 5.28 0.206 18.4-0.764 24.97 0.805zm-21.74 9.668c0.53 9.938 18.385 11.046 17.722-0.806-5.73 0.45-13.31-0.955-17.72 0.806z"/> + <path d="m189.5-1.704c4.365 8.329-2.311 17.572-8.057 20.945-14.153 3.145-20.506-12.574-14.498-21.75 7.31 0.484 16.57-0.996 22.56 0.805zm-21.75 10.473c-0.288 12.131 20.181 11.106 19.332-0.805-4.73-1.068-13.89-0.053-19.33 0.805z"/> + <path d="m-71.5 0.713c1.866 22.747-25.143 19.229-22.555-0.804 7.357-1.891 14.717-1.652 22.555 0.804zm-4.834 6.445h-12.083c-0.491 7.492 12.442 7.27 12.083 0z"/> + <path d="m113.78-0.091c1.591 12.841-6.011 19.97-18.531 16.11-3.495-3.327-6.556-11.017-4.025-17.723 8.461 0.769 12.656-0.516 22.556 1.613zm-19.337 8.055c-2.248 10.146 17.497 9.884 15.305 0-3.25-1.517-9.09 0.215-15.307 0z"/> + <path d="m-59.417-0.897c7.042 0.477 16.03-0.993 21.75 0.806 3.492 11.666-4.688 21.732-16.916 17.722-4.113-3.24-5.908-12.756-4.834-18.528zm4.028 10.473c-0.928 10.566 15.589 8.363 15.303 0-3.462-1.307-11.84-1.307-15.303 0z"/> + <path d="m-1.419-0.897c8.614 12.25-11.412 26.506-20.139 14.499-0.961-4.676 0.003-8.552-1.61-13.693 6.501-2.642 15.752 1.167 21.749-0.806zm-16.111 16.11c5.285 3.028 13.695 0.563 14.5-5.638-3.898-1.743-10.908-0.371-16.11-0.807 0.199 2.489 0.816 4.555 1.61 6.445z"/> + <path d="m38.054-0.091c3.116 11.444-5.586 21.53-18.528 16.915-3.606-3.104-4.571-8.853-4.028-16.111 6.952-3.332 14.424-0.633 22.556-0.804zm-19.334 8.055c-1.618 12.351 16.951 10.428 16.112 0-6.655 0.257-10.288-1.273-16.112 0z"/> + <path d="m75.914 0.713c3.419 20.958-28.009 22.079-24.165 0 6.894-2.494 15.279-1.251 24.165 0zm-19.333 7.251c-2.312 8.975 16.636 11.408 15.304-0.806-4.942 0.426-11.659-0.919-15.304 0.806z"/> + <path d="m-88.417 7.158h12.083c0.359 7.27-12.574 7.492-12.083 0z" fill="#fff"/> + <path d="m34.832 7.964c0.839 10.428-17.732 12.351-16.112 0 5.824-1.273 9.457 0.257 16.112 0z" fill="#fff"/> + <path d="m71.884 7.158c1.332 12.218-17.615 9.781-15.304 0.806 3.646-1.725 10.363-0.38 15.304-0.806z" fill="#fff"/> + <path d="m109.75 7.964c2.192 9.884-17.553 10.146-15.305 0 6.215 0.215 12.055-1.517 15.305 0z" fill="#fff"/> + <path d="m147.61 7.158c0.656 11.852-17.191 10.748-17.722 0.806 4.41-1.761 11.99-0.356 17.72-0.806z" fill="#fff"/> + <path d="m187.08 7.964c0.849 11.911-19.62 12.936-19.332 0.805 5.44-0.858 14.6-1.873 19.33-0.805z" fill="#fff"/> + <path d="m-40.085 9.576c0.283 8.363-16.231 10.566-15.303 0 3.462-1.307 11.84-1.307 15.303 0z" fill="#fff"/> + <path d="m-19.14 8.769c5.202 0.436 12.212-0.933 16.11 0.807-0.805 6.201-9.215 8.666-14.5 5.638-0.794-1.891-1.411-3.957-1.61-6.445z" fill="#fff"/> + <path d="m204 25.686v15.306c-104.84-0.058-199.26 1.636-308.53 2.417-1.876-4.032 0.116-11.933-1.61-16.112 37.658 0.876 71.814-2.208 110.36 0.806 51.482-5.085 134.01-1.075 199.78-2.417z" fill="#fff"/> + <path d="m197.55 46.631c-0.777 57.474 1.235 122.58-0.807 181.25-10.428 5.448-26.192 7.001-35.442-0.806-1.121-57.807-3.209-127.65 0-181.25 9.04-0.767 23.31-1.254 36.25 0.811zm-24.17 11.277c0.132 8.277 15.557 8.897 14.501-3.223-4.48-6.33-14.59-2.628-14.5 3.223zm-0.8 45.912c1.954 2.883 5.012 4.66 9.67 4.834 9.31-6.78-9.39-16.956-9.67-4.83zm3.22 43.51c2.386 0.563 3.507 2.398 7.246 1.609 8.82-7.17-8.96-14.02-7.25-1.61zm-1.61 41.88c-1.605 6.328 8.987 10.591 10.469 4.028 1.86-3.49-7.07-8.18-10.47-4.03z" fill="#fff"/> + <path d="m79.135 46.631c-0.498 53.364 2.17 87.958 0 145-9.397 5.206-29.09 5.795-33.026-4.831-2.507-6.759 0.581-23.275 0-35.446-1.544-32.403-1.031-79.587 0-104.72 11.036 0.392 21.361-2.317 33.026 0.001zm-16.109 16.11c6.863 0.157 9.442-14.524-1.61-11.276-9.041 2.65-2.366 11.186 1.61 11.276zm-4.835 33.833c2.085 5.598 10.659 4.601 12.084-0.806-1.13-6.614-12.346-7.681-12.084 0.806zm2.419 44.306c2.052 5.418 12.679 5.273 12.081-2.419-1.672-4.27-13.566-5.24-12.081 2.42zm-0.807 41.08c0.63 0.18 0.938 0.675 0.807 1.609 3.825 1.621 10.266 1.205 9.665-4.025-1.3-4.2-11.707-3.19-10.472 2.42z" fill="#fff"/> + <path d="m84.774 45.824h33.033c2.163 52.314 0.655 99.574 0.8 156.28-10.213 7.318-26.131 3.386-34.633-3.223-0.64-55.093-2.825-98.969-0.807-150.64-0.042-1.375 0.594-2.083 1.604-2.416zm17.726 18.528c2.746-1.819 5.646-3.484 5.642-8.056-7.1-12.045-20.306 6.059-5.64 8.056zm-6.448 34.638c0.37 3.43 3.438 4.131 7.251 5.639 12.66-7.409-8.575-17.951-7.248-5.64zm0 43.5c-0.213 7.689 11.288 6.673 10.473-0.804-2.94-1.55-8.816-2.84-10.468 0.8zm11.278 35.44c-3.416-5.152-10.935-0.327-10.473 5.639 3.373 6.45 11.333 1.4 10.473-5.64z" fill="#fff"/> + <path d="m124.24 45.824h32.224c-0.719 58.876 1.137 122.88 0 170.77-7.316 7.932-27.779 5.448-33.026-2.419-2.062-63.779-1.142-105.76-0.807-165.94 0.71-0.641 0.49-2.198 1.62-2.406zm23.37 9.667c-4.346-14.15-25.717 10.056-3.225 8.861 1.54-3.286 4.64-4.267 3.23-8.861zm-5.64 52.359c3.265-0.377 4.375-3.326 5.64-7.247-8.81-13.9-19.54 8.86-5.64 7.25zm4.03 33.83c-19.86-7.07-2.97 17.17 0 0zm-7.25 46.73c0.501 3.74 8.584 4.749 8.865 0-0.49-4.87-8.4-4.87-8.87 0z" fill="#fff"/> + <path d="m2.609 46.631c1.874 38.672 0.276 80.815 0.806 120.83-10.667 5.552-28.472 3.113-32.221-6.445-3.144-8.01-1.007-24.596-1.611-37.058-1.188-24.418 1.75-49.179 0.805-75.72 9.499-1.778 20.874-1.68 32.221-1.609zm-21.749 12.081c1.691 6.565 12.855 6.094 12.888-1.611-3.587-4.558-11.344-5.055-12.888 1.611zm4.028 35.445c3.974 1.772 9.797 0.735 9.667-4.026-1.159-2.338-3.659-3.324-6.444-4.029-2.502 1.523-4.929 4.663-3.223 8.055zm-0.805 38.663c-0.052 7.938 11.568 8.322 10.472-0.807-2.517-2.42-8.855-2.09-10.472 0.81z" fill="#fff"/> + <path d="m9.054 46.631h33.026c0.259 44.472-0.654 95.961 0.807 132.11-11.499 8.339-28.48 2.091-34.638-6.444-2.907-34.43-1.098-80.282-1.611-123.25 0.449-1.164 1.256-1.97 2.416-2.419zm12.083 11.277c1.967 5.987 11.93 6.2 11.278-2.417-2.256-4.833-11.349-3.72-11.278 2.417zm6.444 40.277c2.191-2.104 4.654-3.941 4.833-8.055-8.391-7.5-15.288 5.938-4.833 8.055zm0.807 45.915c2.409-2.107 4.637-6.542 1.611-9.666-10.534-5.6-11.506 10.95-1.611 9.67z" fill="#fff"/> + <path d="m-95.667 47.435h26.583c1.345 29.017 1.332 63.621 0 92.64-6.858 3.597-21.211 5.159-26.583-0.806-3.153-25.049-1.35-61.105-1.612-89.416-0.033-1.378 0.598-2.086 1.612-2.419zm7.25 8.056c-0.517 5.887 2.802 7.938 8.861 7.25 1.044-2.446 3.222-3.759 2.416-8.056-3.709-2.202-8.13-1.375-11.277 0.806zm-0.805 29c0.052 4.778 4.323 5.344 9.666 4.833 0.426-2.842 2.363-3.601 0.804-6.444-2.969-2.829-8.971-1.547-10.47 1.611z" fill="#fff"/> + <path d="m-34.445 47.435c1.887 31.239 0.668 74.789 0.807 106.34-8.308 5.286-25.125 5.447-30.612-2.42-0.678-30.103-2.171-74.948 0.805-103.92 9.667-0.005 19.333-0.005 29-0.005zm-16.917 12.084c0.685 3.746 3.286 4.555 9.666 4.028 9.57-10.469-11.559-14.403-9.666-4.028zm-2.416 30.611c1.52 5.433 13.484 5.836 11.277-3.223-3.859-1.644-11.666-3.24-11.277 3.223zm0 39.47c-1.126 6.913 8.344 9.105 11.277 4.832-0.265-4.9-7.475-8.46-11.277-4.83z" fill="#fff"/> + <path d="m61.416 51.464c11.053-3.248 8.474 11.434 1.61 11.276-3.976-0.089-10.651-8.625-1.61-11.276z"/> + <path d="m144.38 64.352c-22.492 1.191-1.121-23.012 3.225-8.861 1.42 4.594-1.68 5.575-3.22 8.861z"/> + <path d="m187.88 54.685c1.056 12.12-14.369 11.5-14.501 3.223-0.09-5.851 10.02-9.553 14.5-3.223z"/> + <path d="m32.415 55.491c0.652 8.617-9.311 8.404-11.278 2.417-0.071-6.137 9.022-7.25 11.278-2.417z"/> + <path d="m108.14 56.296c0.005 4.571-2.896 6.236-5.646 8.056-14.656-1.997-1.45-20.101 5.65-8.056z"/> + <path d="m-77.14 54.685c0.806 4.297-1.375 5.605-2.416 8.056-6.059 0.688-9.378-1.363-8.861-7.25 3.147-2.181 7.568-3.008 11.277-0.806z"/> + <path d="m-41.696 63.547c-6.38 0.529-8.981-0.282-9.666-4.028-1.893-10.375 19.236-6.441 9.666 4.028z"/> + <path d="m-6.252 57.101c-0.032 7.705-11.197 8.177-12.888 1.611 1.544-6.666 9.301-6.169 12.888-1.611z"/> + <path d="m-78.751 82.879c1.559 2.844-0.375 3.603-0.804 6.444-5.343 0.511-9.614-0.055-9.666-4.833 1.498-3.157 7.5-4.439 10.47-1.611z"/> + <path d="m-42.5 86.908c2.207 9.059-9.758 8.655-11.277 3.223-0.39-6.464 7.417-4.868 11.277-3.223z"/> + <path d="m-11.89 86.101c2.785 0.705 5.285 1.691 6.444 4.029 0.131 4.762-5.697 5.799-9.667 4.026-1.705-3.391 0.722-6.531 3.223-8.055z"/> + <path d="m32.415 90.13c-0.18 4.113-2.642 5.95-4.833 8.055-10.456-2.117-3.559-15.555 4.833-8.055z"/> + <path d="m70.275 95.768c-1.425 5.406-9.999 6.409-12.084 0.806-0.262-8.487 10.954-7.42 12.084-0.806z"/> + <path d="m103.3 104.63c-3.813-1.508-6.881-2.209-7.251-5.639-1.324-12.312 19.911-1.77 7.251 5.639z"/> + <path d="m147.61 100.6c-1.265 3.921-2.376 6.87-5.644 7.247-13.9 1.61-3.17-21.15 5.64-7.25z"/> + <path d="m182.25 108.66c-4.658-0.18-7.716-1.951-9.67-4.834 0.28-12.136 18.98-1.96 9.67 4.83z"/> + <path d="m-42.5 134.43c-2.934 4.271-12.403 2.078-11.277-4.828 3.801-3.63 11.011-0.07 11.277 4.83z"/> + <path d="m-5.446 132.02c1.097 9.132-10.523 8.745-10.472 0.807 1.618-2.91 7.956-3.24 10.472-0.81z"/> + <path d="m29.999 134.43c3.026 3.124 0.798 7.559-1.611 9.666-9.895 1.28-8.923-15.27 1.611-9.67z"/> + <path d="m72.691 138.46c0.604 7.692-10.029 7.837-12.081 2.419-1.485-7.66 10.409-6.69 12.081-2.42z"/> + <path d="m106.52 141.68c0.815 7.483-10.686 8.493-10.473 0.804 1.657-3.63 7.533-2.34 10.473-0.8z"/> + <path d="m146 141.68c-2.97 17.17-19.86-7.07 0 0z"/> + <path d="m183.05 148.94c-3.739 0.783-4.86-1.046-7.246-1.609-1.71-12.41 16.07-5.56 7.25 1.61z"/> + <path d="m70.275 179.55c0.601 5.234-5.84 5.65-9.665 4.025 0.131-0.935-0.184-1.437-0.807-1.609-1.235-5.62 9.172-6.63 10.472-2.42z"/> + <path d="m147.61 188.41c-0.281 4.749-8.361 3.74-8.862 0 0.47-4.87 8.38-4.87 8.86 0z"/> + <path d="m184.66 193.24c-1.481 6.562-12.074 2.3-10.469-4.028 3.4-4.15 12.33 0.54 10.47 4.03z"/> + <path d="m-49.751-36.341c4.897 0.528 6.754 0.047 11.278 1.611h-5.638c-1.666-1.826-5.163 2.127-5.64-1.611z"/> + <path d="m203.19 19.242c-0.219 3.174 5.675 0.231 6.448 2.416 2.11 7.132-1.715 17.205 0.803 24.973-1.102 2.386-6.086 0.892-8.054 2.416-0.479 46.865 1.573 88.479 1.609 136.94 0.01 14.573-0.901 29.822-3.223 42.693-9.098 10.734-32.508 10.853-42.695 0.807-0.793-3.458-1.907-5.353-0.803-8.866-6.893 2.205-23.275 5.899-33.03 0.807-3.14-1.64-3.96-5.746-6.444-7.251-0.479-3.426 0.58-5.323 0.807-8.051-11.492 4.032-37.773 4.156-39.475-11.278-12.606 7.739-35.954 3.621-37.859-11.278-14.9 5.401-31.665-0.07-37.861-10.47-15.694 4.241-33.829-1.102-36.249-15.308-10.778 3.6-37.706 5.301-35.444-13.694-12.203 7.214-29.923 0.394-35.445-8.859 0.525-28.134 0.652-53.751 0.807-84.583-0.419-3.607-6.636-1.424-8.055-4.027-0.326-9.524 0.885-15.833 0-24.167 1.17-1.514 5.272-0.097 6.444-1.61 1.295-16.078 1.111-41.7 0-60.417 9.596-4.078 28.396-7.801 38.667-1.611 9.77-3.561 23.629-4.371 33.833 0.805 9.616-5.275 27.909-6.894 37.055 0 7.868-1.952 14.577-4.289 23.362-3.222 4.077 0.497 7.984 3.403 12.082 3.222 3.676-0.16 6.716-3.348 10.472-4.026 4.945-0.894 11.642-0.605 16.923 0 3.658 0.419 7.82 3.251 12.081 3.222 5.953-0.041 11.977-3.984 18.526-4.028 7.854-0.053 13.19 2.27 20.944 4.028 9.159-5.958 28.786-6.633 37.862 0 11.718-9.092 38.838-6.733 45.105 5.638 0.03 18.494-0.34 37.391 0.81 54.778zm-79.75-55.583c7.483 3.139 26.992 4.656 32.224-1.611-7.53-4.914-26.65-5.944-32.22 1.611zm40.28-1.611c3.418 2.755 9.999 2.354 16.11 2.416-0.312-3.715-8.012-0.046-8.051-4.027h12.888v4.027c3.711-0.042 7.874 0.357 10.47-0.805-4.78-6.197-25.68-8.506-31.42-1.611zm-235.22 1.611c-9.865 2.267-18.787-4.736-24.166-1.611 6.585 3.953 22.183 5.679 28.999 0.806-2.534-3.911-11.44-1.447-16.11-3.222-0.36 5.461 10.45-0.249 11.277 4.027zm43.499 0.804c7.029 2.539 25.539 3.125 31.416-0.805-6.747-5.04-26.005-5.93-31.416 0.805zm73.306 0.807c11.037 2.555 23.505 3.346 33.83 0-6.646-6.887-28.311-8.16-33.83 0zm39.469-0.807c7.051 5.748 25.636 2.895 32.227-1.609-6.71-4.687-27.519-5.239-32.226 1.609zm-76.525 0.807c7.27 5.793 26.911 3.584 33.027-1.611-9.368-3.347-26.064-5.974-33.027 1.611zm-70.083-0.807c5.7 2.689 23.743 4.797 29 0-6.277-3.504-23.281-5.52-29 0zm222.33 58.807c10.787 1.335 27.067 1.335 37.858 0-1.607-16.907 1.746-39.386-0.803-57.194-9.556-0.668-27.815 3.252-37.056-1.612-1.15 16.631-1.46 40.202 0 58.806zm-257.78 2.416c9.05-0.349 19.605 0.81 27.388-0.806-0.509-18.822 1.041-39.706-0.804-57.192-10.853 1.822-18.139-0.755-27.39-2.417-0.221 20.154-2.076 41.679 0.806 60.415zm31.417-0.807c9.766 0.974 21.087 0.393 30.61 1.613 1.869-17.467 0.279-38.391 0.806-57.194-8.495-0.163-24.418 1.029-31.416-3.223-2.277 20.259 0.25 39.207 0 58.804zm188.5-57.999c-0.784 15.927-1.855 38.76 0.807 57.194h31.417c1.77-22.794 0.868-36.623 1.606-57.999h-1.606c-9.77 3.022-21.11 1.977-32.23 0.805zm-39.475 0.807c-2.121 19.178-1.06 34.27-0.807 55.583 10.702 2.758 19.532 0.084 35.449 0.805-0.046-20.616 1.557-35.851 0-57.194-10.77 2.148-24.645 4.499-34.645 0.806zm-113.58 0c-0.812 16.786-0.275 38.76 0.805 57.999 10.146-0.593 20.385-1.098 31.416-0.806 0.913-15.194 1.622-40.41 0.805-57.192-11.126 0.66-21.403 2.036-33.026-0.001zm37.055 57.192h34.638c1.399-19.358 1.102-39.404 0-56.388-10.13 1.426-25.432 4.981-34.638 0-0.128 13.682-2.008 38.463 0 56.388zm39.471-55.581c-1.714 19.853-0.668 40.761 0 55.581h32.221c-1.265-18.326 2.438-43.177-1.606-56.388-10.267 1.279-20.002 1.686-30.615 0.807zm-41.888 58.805c-38.543-3.014-72.702 0.07-110.36-0.806 1.727 4.179-0.266 12.08 1.61 16.112 109.27-0.777 203.68-2.472 308.52-2.417v-15.306c-65.76 1.342-148.29-2.668-199.77 2.417zm157.08 17.721c-3.209 53.591-1.121 123.44 0 181.25 9.25 7.801 25.01 6.247 35.442 0.8 2.042-58.666 0.029-123.77 0.807-181.25-12.94-2.054-27.21-1.567-36.25-0.796zm-115.19 0.807c-1.031 25.132-1.544 72.316 0 104.72 0.581 12.171-2.507 28.688 0 35.446 3.937 10.626 23.629 10.037 33.026 4.831 2.17-57.039-0.498-91.63 0-145-11.665-2.317-21.99 0.392-33.026 0.001zm37.056 1.611c-2.022 51.668 0.166 95.544 0.803 150.64 8.509 6.608 24.427 10.541 34.64 3.223-0.15-56.703 1.356-103.96-0.807-156.28h-33.026c-1.01 0.337-1.646 1.045-1.609 2.422zm39.475 0c-0.335 60.183-1.256 102.16 0.807 165.94 5.247 7.867 25.71 10.351 33.026 2.419 1.137-47.898-0.719-111.9 0-170.77h-32.224c-1.15 0.202-0.93 1.759-1.62 2.412zm-152.25 0c0.947 26.539-1.99 51.299-0.805 75.72 0.604 12.462-1.533 29.048 1.611 37.058 3.749 9.559 21.555 11.997 32.221 6.445-0.53-40.01 1.064-82.154-0.806-120.83-11.347-0.07-22.722-0.168-32.221 1.612zm36.25 0.804c0.513 42.967-1.296 88.819 1.611 123.25 6.158 8.535 23.139 14.783 34.638 6.444-1.464-36.147-0.548-87.637-0.807-132.11h-33.026c-1.16 0.45-1.967 1.256-2.416 2.416zm-103.92 0.807c0.262 28.311-1.542 64.367 1.612 89.416 5.376 5.965 19.726 4.402 26.583 0.799 1.332-29.015 1.345-63.619 0-92.636h-26.583c-1.015 0.334-1.646 1.042-1.612 2.419zm33.833-2.418c-2.977 28.967-1.48 73.812-0.805 103.92 5.487 7.867 22.304 7.706 30.612 2.42-0.142-31.543 1.08-75.096-0.807-106.34-9.667-0.005-19.333-0.005-29-0.005z"/> + <path d="m96.859 183.57c-0.462-5.963 7.057-10.791 10.473-5.639 0.86 7.04-7.1 12.09-10.471 5.64z"/> +<metadata><rdf:RDF><cc:Work><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/><dc:publisher><cc:Agent rdf:about="http://openclipart.org/"><dc:title>Openclipart</dc:title></cc:Agent></dc:publisher><dc:title>pan pipes</dc:title><dc:date>2007-07-20T14:57:30</dc:date><dc:description>I cannot find what the proper name of this instrument must be - any idea post here. For now I am calling it pan pipes but I don't think they have finger holes. This is from a concert brochure for the 54th Regt. Band from Library of Congress</dc:description><dc:source>http://openclipart.org/detail/4518/pan-pipes-by-johnny_automatic</dc:source><dc:creator><cc:Agent><dc:title>johnny_automatic</dc:title></cc:Agent></dc:creator><dc:subject><rdf:Bag><rdf:li>clip art</rdf:li><rdf:li>clipart</rdf:li><rdf:li>externalsource</rdf:li><rdf:li>flute</rdf:li><rdf:li>image</rdf:li><rdf:li>instrument</rdf:li><rdf:li>loc</rdf:li><rdf:li>media</rdf:li><rdf:li>music</rdf:li><rdf:li>musical</rdf:li><rdf:li>pipes</rdf:li><rdf:li>png</rdf:li><rdf:li>public domain</rdf:li><rdf:li>svg</rdf:li></rdf:Bag></dc:subject></cc:Work><cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/><cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/><cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/></cc:License></rdf:RDF></metadata></svg> diff --git a/site/styles.css b/site/styles.css index e3b4b52..5ceb2b1 100644 --- a/site/styles.css +++ b/site/styles.css @@ -13,14 +13,18 @@ a { justify-content: center; flex-wrap: nowrap; flex-direction: column; - margin-top: 0px; + margin: 0 0 0 0; min-height: 100vh; } #header { text-align: center; - margin-top: 0px; - margin-bottom: 10px; + box-shadow: 0px 0px 7px rgb(14, 15, 17); + padding: 0px 10px 0px 10px; + margin-top: -10px; + margin-left: -8px; + margin-right: -8px; + margin-bottom: 0px; } #content { diff --git a/src/api.ts b/src/api.ts index 8d09c99..1565257 100644 --- a/src/api.ts +++ b/src/api.ts @@ -5,35 +5,44 @@ function init(conf: object){ config = conf; } -async function register(name: string, password: string, streamer: boolean) { - if(!config.registration){ - return {"error":"registration disabled"}; - } - else { - if(name.includes(';') || name.includes(' ')) return {"error":"illegal characters"}; - let s: boolean; - if(streamer && config.streamKeys) s = true; - else s = false; - let r: boolean = await db.addUser(name, password, s, false); - if(r) return {"success":""}; - else return {"error":""}; +async function register(name: string, password: string, confirm: string) { + if(!config.registration) return {"error":"registration disabled"}; + if(name.includes(';') || name.includes(' ') || name.includes('\'')) return {"error":"illegal characters"}; + if(password !== confirm) return {"error":"mismatched passwords"}; + for(let i=0;i<config.restrictedNames.length;i++){ + if (name === config.restrictedNames[i]) return {"error":"restricted name"}; } + let r: boolean = await db.addUser(name, password); + if(r) return {"success":""}; + return {"error":""}; } -async function login(name: string, pass: string) { - return await db.validatePassword(name, pass); +async function update(name: string, password: string, title: string, bio: string, record: boolean){ + if(!name || !password) return {"error":"Insufficient parameters"}; + let auth: boolean = await db.validatePassword(name, password); + if(!auth) return {"error":"Username or Password Incorrect"}; + await db.query('UPDATE user_meta set title='+db.raw.escape(title)+', about='+db.raw.escape(bio)+' where username='+db.raw.escape(name)); + if(!record) await db.query('UPDATE users set record_flag=false where username='+db.raw.escape(name)); + else await db.query('UPDATE users set record_flag=true where username='+db.raw.escape(name)); + return {"success":""}; } -async function users(num: number) { - return await db.query('select username from users limit '+num); +async function changepwd(name: string, password: string, newpwd: string){ + if(!name || !password) return {"error":"Insufficient parameters"}; + let auth: boolean = await db.validatePassword(name, password); + if(!auth) return {"error":"Username or Password Incorrect"}; + let newhash: string = await db.hash(newpwd); + await db.query('UPDATE users set password_hash='+db.raw.escape(newhash)+'where username='+db.raw.escape(name)+' limit 1'); + return {"success":""}; } -async function user(name: string) { - +async function changesk(name: string, password: string){ + if(!name || !password) return {"error":"Insufficient parameters"}; + let auth: boolean = await db.validatePassword(name, password); + if(!auth) return {"error":"Username or Password Incorrect"}; + 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}; } -async function instance() { - -} - -export { init, register }; \ No newline at end of file +export { init, register, update, changepwd, changesk }; \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts index 10ab855..f4d58ba 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,8 +6,6 @@ db.init(config.database, config.bcrypt); flags.defineString('add', '', 'User to add'); flags.defineString('remove', '', 'User to remove'); -flags.defineString('mkstreamer', '', 'Give a stream key to a user'); -flags.defineString('rmstreamer', '', 'Remove a stream key from a user'); flags.defineString('password', '', 'password to hash'); flags.defineBoolean('admin'); flags.defineBoolean('streamer'); @@ -15,7 +13,7 @@ flags.defineBoolean('streamer'); flags.parse(); if(flags.get('add') !== ''){ - db.addUser(flags.get('add'), flags.get('password'), flags.get('streamer'), flags.get('admin')).then((result) => { + db.addUser(flags.get('add'), flags.get('password')).then((result) => { if(result) console.log("User added successfully."); else console.log("Could not add user. Is the password field empty?"); process.exit(); @@ -28,20 +26,4 @@ if(flags.get('remove') !== ''){ else console.log("Could not remove user."); process.exit(); }); -} - -if(flags.get('mkstreamer') !== ''){ - db.addStreamKey(flags.get('mkstreamer')).then((result) => { - if(result) console.log("Key added successfully."); - else console.log("Could not add key."); - process.exit(); - }); -} - -if(flags.get('rmstreamer') !== ''){ - db.rmStreamKey(flags.get('rmstreamer')).then((result) => { - if(result) console.log("Key removed successfully."); - else console.log("Could not remove key."); - process.exit(); - }); } \ No newline at end of file diff --git a/src/controller.ts b/src/controller.ts index c727a04..4e52fe3 100644 --- a/src/controller.ts +++ b/src/controller.ts @@ -11,13 +11,14 @@ function run(): void{ const satyr: object = { privateEndpoint: config.media.privateEndpoint, record: config.media.record, - streamKeys: config.media.streamKeys, registration: config.satyr.registration, webFormat: config.satyr.webFormat, restrictedNames: config.satyr.restrictedNames, name: config.satyr.name, domain: config.satyr.domain, - email: config.satyr.email + email: config.satyr.email, + rootredirect: config.satyr.rootredirect, + version: process.env.npm_package_version }; const nms: object = { logType: config.server.logs, diff --git a/src/database.ts b/src/database.ts index 3271cb3..e69d70c 100644 --- a/src/database.ts +++ b/src/database.ts @@ -10,24 +10,23 @@ function init (db: object, bcrypt: object){ cryptoconfig = bcrypt; } -async function addUser(name: string, password: string, streamer: boolean, admin: boolean){ +async function addUser(name: string, password: string){ //does not respect registration setting in config - //nor stream keys if(password === '') return false; - let key: string = ' '; - if (streamer) key = await genKey(); + let key: string = await genKey(); let hash: string = await bcrypt.hash(password, cryptoconfig.saltRounds); - let dupe = await query('select * from users where username=\''+name+'\''); + let dupe = await query('select * from users where username='+raw.escape(name)); if(dupe[0]) return false; - let q: string = 'INSERT INTO users (username, password_hash, stream_key, record_flag, is_mod) VALUES (\''+name+'\', \''+hash+'\', \''+key+'\', 0, '+admin+')'; - await query(q); + await query('INSERT INTO users (username, password_hash, stream_key, record_flag) VALUES ('+raw.escape(name)+', '+raw.escape(hash)+', '+raw.escape(key)+', 0'); + await query('INSERT INTO user_meta (username, title, about, live) VALUES ('+raw.escape(name)+',\'\',\'\',false)'); return true; } async function rmUser(name: string){ - let exist = await query('select * from users where username=\''+name+'\''); + let exist = await query('select * from users where username='+raw.escape(name)); if(!exist[0]) return false; - await query('delete from users where username=\''+name+'\' limit 1'); + await query('delete from users where username='+raw.escape(name)+' limit 1'); + await query('delete from user_meta where username='+raw.escape(name)+' limit 1'); return true; } @@ -38,21 +37,6 @@ async function genKey(){ else return key; } -async function addStreamKey(name: string){ - let exist = await query('select * from users where username=\''+name+'\''); - if(!exist[0]) return false; - let key = await genKey(); - await query('update users set stream_key=\''+key+'\' where username=\''+name+'\' limit 1'); - return true; -} - -async function rmStreamKey(name: string){ - let exist = await query('select * from users where username=\''+name+'\''); - if(!exist[0]) return false; - await query('update users set stream_key=\'\' where username=\''+name+'\' limit 1'); - return true; -} - async function query(query: string){ return new Promise(resolve => raw.query(query, (error, results, fields) => { if(error) throw error; @@ -61,8 +45,12 @@ async function query(query: string){ } async function validatePassword(username: string, password: string){ - let pass: any= await query('select password from users where username=\''+username+'\' limit 1'); - return await bcrypt.compare(password, pass[0].password_hash); + let pass: any = await query('select password_hash from users where username='+raw.escape(username)+' limit 1'); + return await bcrypt.compare(password, pass[0].password_hash.toString()); } -export { query, raw, init, addUser, rmUser, addStreamKey, rmStreamKey, validatePassword }; \ No newline at end of file +async function hash(pwd){ + return await bcrypt.hash(pwd, cryptoconfig.saltRounds); +} + +export { query, raw, init, addUser, rmUser, validatePassword, hash, genKey }; \ No newline at end of file diff --git a/src/http.ts b/src/http.ts index 507692d..5f07be4 100644 --- a/src/http.ts +++ b/src/http.ts @@ -1,6 +1,7 @@ import * as express from "express"; import * as njk from "nunjucks"; import * as bodyparser from "body-parser"; +import * as fs from "fs"; import * as api from "./api"; import * as db from "./database"; @@ -18,30 +19,95 @@ function init(satyr: any){ sitename: satyr.name, domain: satyr.domain, email: satyr.email, - user: '', - streamtitle: '', + rootredirect: satyr.rootredirect, + version: satyr.version }; app.use(bodyparser.json()); app.use(bodyparser.urlencoded({ extended: true })); + //site handlers app.get('/', (req, res) => { - res.render('index.njk', njkconf); + res.redirect(njkconf.rootredirect); }); app.get('/about', (req, res) => { res.render('about.njk', njkconf); }); - app.get('/users/*', (req, res) => { - njkconf.user = req.url.split('/')[2].toLowerCase(); - res.render('user.njk', njkconf); - }); - app.get('/registration', (req, res) => { - res.render('registration.njk', njkconf); - }); - app.post('/api/register', (req, res) => { - api.register(req.body.username, req.body.password, req.body.streamer).then( (result) => { - res.send({"error":""}); + app.get('/users', (req, res) => { + db.query('select username from users').then((result) => { + njkconf.list = result; + res.render('list.njk', njkconf); + njkconf.list = ''; }); }); + app.get('/users/live', (req, res) => { + db.query('select username,title from user_meta where live=1;').then((result) => { + njkconf.list = result; + res.render('live.njk', njkconf); + njkconf.list = ''; + }); + }); + app.get('/users/*', (req, res) => { + njkconf.user = req.url.split('/')[2].toLowerCase(); + db.query('select title,about from user_meta where username='+db.raw.escape(njkconf.user)).then((result) => { + if(result[0]){ + njkconf.streamtitle = result[0].title; + njkconf.about = result[0].about; + res.render('user.njk', njkconf); + } + else res.render('404.njk', njkconf); + }); + }); + app.get('/vods/*', (req, res) => { + njkconf.user = req.url.split('/')[2].toLowerCase(); + db.query('select username from user_meta where username='+db.raw.escape(njkconf.user)).then((result) => { + if(result[0]){ + fs.readdir('./site/live/'+njkconf.user, {withFileTypes: true} , (err, files) => { + if(files) njkconf.list = files.filter(fn => fn.name.endsWith('.mp4')); + else njkconf.list = []; + res.render('vods.njk', njkconf); + }); + } + else res.render('404.njk', njkconf); + }); + }); + app.get('/register', (req, res) => { + res.render('registration.njk', njkconf); + }); + app.get('/profile', (req, res) => { + res.render('profile.njk', njkconf); + }); + app.get('/changepwd', (req, res) => { + res.render('changepwd.njk', njkconf); + }); + app.get('/changesk', (req, res) => { + res.render('changesk.njk', njkconf); + }); + //api handlers + app.post('/api/register', (req, res) => { + api.register(req.body.username, req.body.password, req.body.confirm).then( (result) => { + res.send(result); + }); + }); + app.post('/api/user', (req, res) => { + api.update(req.body.username, req.body.password, req.body.title, req.body.bio, req.body.record).then((result) => { + res.send(result); + }); + }); + app.post('/api/user/password', (req, res) => { + api.changepwd(req.body.username, req.body.password, req.body.newpassword).then((result) => { + res.send(result); + }); + }); + app.post('/api/user/streamkey', (req, res) => { + api.changesk(req.body.username, req.body.password).then((result) => { + res.send(result); + }) + }); + //static files if nothing else matches first app.use(express.static('site')); + //404 Handler + app.use(function (req, res, next) { + res.status(404).render('404.njk', njkconf); + }); } export { init }; \ No newline at end of file diff --git a/src/server.ts b/src/server.ts index 2b1258f..cc20280 100644 --- a/src/server.ts +++ b/src/server.ts @@ -8,7 +8,7 @@ function init (mediaconfig: any, satyrconfig: any) { nms.run(); nms.on('postPublish', (id, StreamPath, args) => { - console.log("[NodeMediaServer] Prepublish Hook for stream:",id); + console.log("[NodeMediaServer] Publish Hook for stream:",id); let session = nms.getSession(id); let app: string = StreamPath.split("/")[1]; let key: string = StreamPath.split("/")[2]; @@ -31,6 +31,8 @@ function init (mediaconfig: any, satyrconfig: any) { return false; } console.log("[NodeMediaServer] Public endpoint, checking record flag."); + //set live flag + db.query('update user_meta set live=true where username=\''+key+'\' limit 1'); //if this stream is from the public endpoint, check if we should be recording return db.query('select username,record_flag from users where username=\''+key+'\' limit 1').then((results) => { if(results[0].record_flag && satyrconfig.record){ @@ -61,7 +63,11 @@ function init (mediaconfig: any, satyrconfig: any) { //if the url is formatted correctly and the user is streaming to the correct private endpoint //grab the username from the database and redirect the stream there if the key is valid //otherwise kill the session - db.query('select username from users where stream_key=\''+key+'\' limit 1').then((results) => { + if(key.includes(' ')) { + session.reject(); + return false; + } + db.query('select username from users where stream_key='+db.raw.escape(key)+' limit 1').then((results) => { if(results[0]){ exec('ffmpeg -analyzeduration 0 -i rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+satyrconfig.privateEndpoint+'/'+key+' -vcodec copy -acodec copy -crf 18 -f flv rtmp://127.0.0.1:'+mediaconfig.rtmp.port+'/'+mediaconfig.trans.tasks[0].app+'/'+results[0].username); console.log('[NodeMediaServer] Stream key okay for stream:',id); @@ -72,6 +78,13 @@ function init (mediaconfig: any, satyrconfig: any) { } }); }); + nms.on('donePublish', (id, StreamPath, args) => { + let app: string = StreamPath.split("/")[1]; + let key: string = StreamPath.split("/")[2]; + if(app === mediaconfig.trans.tasks[0].app) { + db.query('update user_meta set live=false where username=\''+key+'\' limit 1'); + } + }); nms.on('prePlay', (id, StreamPath, args) => { let session = nms.getSession(id); let app: string = StreamPath.split("/")[1]; diff --git a/templates/index.njk b/templates/404.njk similarity index 64% rename from templates/index.njk rename to templates/404.njk index 61e86ce..add9710 100644 --- a/templates/index.njk +++ b/templates/404.njk @@ -1,4 +1,5 @@ {% extends "base.njk" %} {% block content %} -What to put on index? +<p></p> +Couldn't find that page! {% endblock %} \ No newline at end of file diff --git a/templates/about.html b/templates/about.html index f9ffa57..a298cb0 100644 --- a/templates/about.html +++ b/templates/about.html @@ -1 +1 @@ -<p>Add a description of your instance here!</p> \ No newline at end of file +<p>Add a description of your instance here!</br>You can find this file in templates/about.html</p> \ No newline at end of file diff --git a/templates/base.njk b/templates/base.njk index c751750..c9aad78 100644 --- a/templates/base.njk +++ b/templates/base.njk @@ -1,12 +1,14 @@ <!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"> <title>{{ sitename }}</title> </head> <body> <div id="wrapper"> <div id="header"> - <span style="float:left;"><h4><a href="/">{{ sitename }}</a> | <a href="/users/live">Live</a> <a href="/users">Users</a> <a href="/about">About</a></h4></span><span style="float:right;"><h4>| <a href="/login">Login</a></h4></span> + <span style="float:left;"><h4><a href="/">{{ sitename }}</a> | <a href="/users">Users</a> <a href="/users/live">Live</a> <a href="/about">About</a></h4></span><span style="float:right;"><h4>| <a href="/profile">Profile</a></h4></span> </div> <div id="content"> {% block content %} @@ -17,10 +19,10 @@ <div> <b>Satyr</b></br> <a href="https://gitlab.com/knotteye/satyr">About</a></br> - <a href="">v0.1.0</a> + <a href="https://gitlab.com/knotteye/satyr/-/releases">v{{ version }}</a> </div> <div> - <img src="/satyr.png" height="50" /> + <img src="/logo.svg" height="50" /> </div> <div> <b>{{ sitename }}</b></br> diff --git a/templates/changepwd.njk b/templates/changepwd.njk new file mode 100644 index 0000000..aa29838 --- /dev/null +++ b/templates/changepwd.njk @@ -0,0 +1,12 @@ +{% extends "base.njk" %} +{% block content %} +<h3>Change your password on {{ sitename }}</h3><span style="font-size: small;">Not registered yet? Sign up <a href="/register">here</a>.</br> Update your <a href="/profile">profile</a> or <a href="/changesk">stream key</a>.</span> +<p></p> + <form action="/api/user/password" method="POST" target="responseFrame"> + Username: </br><input type="text" name="username" style="min-width: 300px" placeholder="e.g. lain"/></br> + Password: </br><input type="password" name="password" style="min-width: 300px"/></br> + New Password: </br><input type="password" name="newpassword" style="min-width: 300px"/></br> + <input type="submit" value="Submit"> + </form> + <iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe> +{% endblock %} \ No newline at end of file diff --git a/templates/changesk.njk b/templates/changesk.njk new file mode 100644 index 0000000..d5e6dbc --- /dev/null +++ b/templates/changesk.njk @@ -0,0 +1,11 @@ +{% extends "base.njk" %} +{% block content %} +<h3>Change your password on {{ sitename }}</h3><span style="font-size: small;">Not registered yet? Sign up <a href="/register">here</a>.</br> Update your <a href="/profile">profile</a> or <a href="/changepwd">password</a>.</span> +<p></p> + <form action="/api/user/streamkey" method="POST" target="responseFrame"> + Username: </br><input type="text" name="username" style="min-width: 300px" placeholder="e.g. lain"/></br> + Password: </br><input type="password" name="password" style="min-width: 300px"/></br> + <input type="submit" value="Submit"> + </form> + <iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe> +{% endblock %} \ No newline at end of file diff --git a/templates/list.njk b/templates/list.njk new file mode 100644 index 0000000..75e8f73 --- /dev/null +++ b/templates/list.njk @@ -0,0 +1,9 @@ +{% extends "base.njk" %} +{% block content %} + <h3>Streaming on {{ sitename }}</h3> + {% asyncEach user in list%} + <a href="/users/{{user.username}}">{{ user.username }}</a></br></br> + {% else %} + No users found! + {% endeach %} +{% endblock %} \ No newline at end of file diff --git a/templates/live.njk b/templates/live.njk new file mode 100644 index 0000000..04bc2a9 --- /dev/null +++ b/templates/live.njk @@ -0,0 +1,9 @@ +{% extends "base.njk" %} +{% block content %} + <h3>Currently live on {{ sitename }}</h3> + {% for user in list%} + <a href="/users/{{user.username}}">{{ user.username | capitalize}} | {{user.title}}</a></br></br> + {% else %} + No one is live! + {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/templates/login.njk b/templates/login.njk deleted file mode 100644 index e69de29..0000000 diff --git a/templates/profile.njk b/templates/profile.njk index e69de29..465f061 100644 --- a/templates/profile.njk +++ b/templates/profile.njk @@ -0,0 +1,14 @@ +{% extends "base.njk" %} +{% block content %} +<h3>Update your profile on {{ sitename }}</h3><span style="font-size: small;">Not registered yet? Sign up <a href="/register">here</a>.</br> Change your <a href="/changepwd">password</a> or <a href="/changesk">stream key</a>.</span> +<p></p> + <form action="/api/user" method="POST" target="responseFrame"> + Username: </br><input type="text" name="username" style="min-width: 300px" placeholder="e.g. lain"/></br> + Password: </br><input type="password" name="password" style="min-width: 300px"/></br> + Stream Title: </br><input type="text" name="title" style="min-width: 300px"/></br> + Bio: </br><input type="text" name="bio" style="min-width: 300px; min-height: 150px;"/></br> + Record VODs: <input type="checkbox" name="record" value="true"></br> + <input type="submit" value="Submit"> + </form> + <iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe> +{% endblock %} \ No newline at end of file diff --git a/templates/registration.njk b/templates/registration.njk index f836c5a..2bdfe0c 100644 --- a/templates/registration.njk +++ b/templates/registration.njk @@ -2,12 +2,13 @@ {% block content %} <div id="jscontainer" style="height: 100%;"> <div id="jschild" style="width: 50%;height: 100%;text-align: left;margin: 20px;"> - <form action="/api/register" method="POST" target="_self"> + <form action="/api/register" method="POST" target="responseFrame"> Username: </br><input type="text" name="username" style="min-width: 300px" placeholder="e.g. lain"/></br> Password: </br><input type="password" name="password" style="min-width: 300px"/></br> - Request Stream Key: <input type="checkbox" name="streamer" value="true" style="min-heigh: 50px;"> </br> + Confirm: </br><input type="password" name="confirm" style="min-width: 300px"/></br> <input type="submit" value="Submit"> </form> + <iframe name="responseFrame" border="0" frameborder="0" style="display: inline;"></iframe> </div> <div id="jschild" style="width: 50%;height: 100%;text-align: left;margin: 20px;"> {% include "tos.html" %} diff --git a/templates/tos.html b/templates/tos.html index a9cb745..a13c391 100644 --- a/templates/tos.html +++ b/templates/tos.html @@ -1,2 +1,2 @@ -This is example terms of service!</br> +This is an example TOS!</br> You should change it by editing templates/tos.html \ No newline at end of file diff --git a/templates/user.njk b/templates/user.njk index 081341a..d8a12c4 100644 --- a/templates/user.njk +++ b/templates/user.njk @@ -1,6 +1,7 @@ {% extends "base.njk" %} {% block content %} - <span style="float: left;font-size: large;"><b>{{ user | capitalize }}'s Stream</b></span><span style="float: right;font-size: large;">Direct Links: <a href="rtmp://{{ domain }}/live/{{ user }}">RTMP</a> <a href="/live/{{ user }}/index.m3u8">HLS</a></span> + </br> + <span style="float: left;font-size: large;"><b>{{ user }} | {{ streamtitle | escape }}</b></span><span style="float: right;font-size: large;"> Links | <a href="/vods/{{ user }}">VODs</a></span> <div id="jscontainer"> <div id="jschild" style="width: 70%;height: 100%;"> <video controls poster="/thumbnail.jpg" class="video-js vjs-default-skin" id="live-video" style="width:100%;height:100%;"></video> @@ -28,4 +29,6 @@ }); }) </script></br> + <noscript>The webclients for the stream and the chat require javascript, but feel free to use the direct links above!</br></br></noscript> + {{ about | escape }} {% endblock %} \ No newline at end of file diff --git a/templates/vods.njk b/templates/vods.njk new file mode 100644 index 0000000..97c4aaf --- /dev/null +++ b/templates/vods.njk @@ -0,0 +1,9 @@ +{% extends "base.njk" %} +{% block content %} + <h3>{{ user }}'s VODs</h3> + {% asyncEach vid in list%} + <a href="/live/{{ user }}/{{ vid.name }}">{{ vid.name }}</a></br></br> + {% else %} + No recordings found! + {% endeach %} +{% endblock %} \ No newline at end of file