mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-27 01:48:33 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into searchSegments
This commit is contained in:
68
.gitignore
vendored
68
.gitignore
vendored
@@ -2,47 +2,9 @@
|
|||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
node_modules/
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
|
||||||
typings/
|
|
||||||
|
|
||||||
# TypeScript cache
|
# TypeScript cache
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
@@ -53,40 +15,10 @@ typings/
|
|||||||
# Optional eslint cache
|
# Optional eslint cache
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
# dotenv environment variables file
|
||||||
.env
|
.env
|
||||||
.env.test
|
.env.test
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# next.js build output
|
|
||||||
.next
|
|
||||||
|
|
||||||
# nuxt.js build output
|
|
||||||
.nuxt
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# Databases
|
# Databases
|
||||||
databases/sponsorTimes.db
|
databases/sponsorTimes.db
|
||||||
databases/sponsorTimes.db-shm
|
databases/sponsorTimes.db-shm
|
||||||
|
|||||||
@@ -34,4 +34,4 @@ If you want to make changes, run `npm run dev` to automatically reload the serve
|
|||||||
|
|
||||||
# API Docs
|
# API Docs
|
||||||
|
|
||||||
Available [here](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs)
|
Available [here](https://wiki.sponsor.ajay.app/index.php/API_Docs)
|
||||||
|
|||||||
456
nginx/nginx.conf
456
nginx/nginx.conf
@@ -2,281 +2,231 @@ worker_processes 8;
|
|||||||
worker_rlimit_nofile 65536;
|
worker_rlimit_nofile 65536;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 432768; ## Default: 1024
|
worker_connections 432768; # Default: 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
http {
|
http {
|
||||||
log_format no_ip '$remote_user [$time_local] '
|
log_format no_ip '$remote_user [$time_local] '
|
||||||
'"$request" $status $body_bytes_sent '
|
'"$request" $status $body_bytes_sent '
|
||||||
|
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
|
||||||
|
|
||||||
|
log_format user_agent '[$time_local] '
|
||||||
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
|
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
|
||||||
|
|
||||||
log_format user_agent '[$time_local] '
|
include /etc/nginx/mime.types;
|
||||||
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
|
include /etc/nginx/proxy.conf;
|
||||||
|
include /etc/nginx/fastcgi.conf;
|
||||||
|
|
||||||
include /etc/nginx/mime.types;
|
upstream backend_GET {
|
||||||
include /etc/nginx/proxy.conf;
|
least_conn;
|
||||||
include /etc/nginx/fastcgi.conf;
|
#server localhost:4441;
|
||||||
|
#server localhost:4442;
|
||||||
upstream backend_GET {
|
#server localhost:4443;
|
||||||
least_conn;
|
#server localhost:4444;
|
||||||
#server localhost:4441;
|
#server localhost:4445;
|
||||||
#server localhost:4442;
|
#server localhost:4446;
|
||||||
#server localhost:4443;
|
#server localhost:4447;
|
||||||
#server localhost:4444;
|
#server localhost:4448;
|
||||||
#server localhost:4445;
|
|
||||||
#server localhost:4446;
|
|
||||||
#server localhost:4447;
|
|
||||||
#server localhost:4448;
|
|
||||||
|
|
||||||
server 10.0.0.3:4441;
|
server 10.0.0.3:4441;
|
||||||
server 10.0.0.3:4442;
|
server 10.0.0.3:4442;
|
||||||
|
|
||||||
#server 134.209.69.251:80 backup;
|
#server 134.209.69.251:80 backup;
|
||||||
|
|
||||||
server 116.203.32.253:80 backup;
|
server 116.203.32.253:80 backup;
|
||||||
#server 116.203.32.253:80;
|
#server 116.203.32.253:80;
|
||||||
}
|
}
|
||||||
upstream backend_POST {
|
upstream backend_POST {
|
||||||
#server localhost:4441;
|
#server localhost:4441;
|
||||||
#server localhost:4442;
|
#server localhost:4442;
|
||||||
server 10.0.0.3:4441;
|
server 10.0.0.3:4441;
|
||||||
#server 10.0.0.3:4442;
|
#server 10.0.0.3:4442;
|
||||||
}
|
}
|
||||||
upstream backend_db {
|
upstream backend_db {
|
||||||
server localhost:4441;
|
server localhost:4441;
|
||||||
#server 10.0.0.3:4441;
|
#server 10.0.0.3:4441;
|
||||||
}
|
|
||||||
|
|
||||||
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHEZONE:10m inactive=60m max_size=400m;
|
|
||||||
proxy_cache_key "$scheme$request_method$host$request_uri";
|
|
||||||
add_header X-Cache $upstream_cache_status;
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name sponsor.ajay.app api.sponsor.ajay.app;
|
|
||||||
|
|
||||||
error_page 404 /404.html;
|
|
||||||
#error_page 500 @myerrordirective_500;
|
|
||||||
#error_page 502 @myerrordirective_502;
|
|
||||||
#error_page 504 @myerrordirective_504;
|
|
||||||
#location = /404 {
|
|
||||||
# root /home/sbadmin/caddy/SponsorBlockSite/public-prod;
|
|
||||||
# internal;
|
|
||||||
#}
|
|
||||||
|
|
||||||
#proxy_send_timeout 120s;
|
|
||||||
|
|
||||||
#location @myerrordirective_500 {
|
|
||||||
# return 400 "Internal Server Error";
|
|
||||||
#}
|
|
||||||
#location @myerrordirective_502 {
|
|
||||||
# return 400 "Bad Gateway";
|
|
||||||
#}
|
|
||||||
#location @myerrordirective_504 {
|
|
||||||
# return 400 "Gateway Timeout";
|
|
||||||
#}
|
|
||||||
|
|
||||||
|
|
||||||
location /news {
|
|
||||||
return 301 https://blog.ajay.app/sponsorblock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location /viewer {
|
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHEZONE:10m inactive=60m max_size=400m;
|
||||||
return 301 https://sb.ltn.fi;
|
proxy_cache_key "$scheme$request_method$host$request_uri";
|
||||||
}
|
add_header X-Cache $upstream_cache_status;
|
||||||
|
|
||||||
location /test/ {
|
server {
|
||||||
proxy_pass http://localhost:4440/;
|
server_name sponsor.ajay.app api.sponsor.ajay.app;
|
||||||
#proxy_pass https://sbtest.etcinit.com/;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /api/skipSegments {
|
error_page 404 /404.html;
|
||||||
#return 200 "[]";
|
#error_page 500 @myerrordirective_500;
|
||||||
proxy_pass http://backend_$request_method;
|
#error_page 502 @myerrordirective_502;
|
||||||
#proxy_cache CACHEZONE;
|
#error_page 504 @myerrordirective_504;
|
||||||
#proxy_cache_valid 2m;
|
#location = /404 {
|
||||||
|
# root /home/sbadmin/caddy/SponsorBlockSite/public-prod;
|
||||||
|
# internal;
|
||||||
|
#}
|
||||||
|
|
||||||
if ($request_method = POST) {
|
#proxy_send_timeout 120s;
|
||||||
access_log /etc/nginx/logs/submissions.log user_agent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location /api/getTopUsers {
|
#location @myerrordirective_500 {
|
||||||
proxy_pass http://backend_GET;
|
# return 400 "Internal Server Error";
|
||||||
proxy_cache CACHEZONE;
|
#}
|
||||||
proxy_cache_valid 20m;
|
#location @myerrordirective_502 {
|
||||||
}
|
# return 400 "Bad Gateway";
|
||||||
|
#}
|
||||||
|
#location @myerrordirective_504 {
|
||||||
|
# return 400 "Gateway Timeout";
|
||||||
|
#}
|
||||||
|
|
||||||
location /api/getTotalStats {
|
location /news {
|
||||||
proxy_pass http://backend_GET;
|
return 301 https://blog.ajay.app/sponsorblock;
|
||||||
#return 200 "";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
location /viewer {
|
||||||
location /api/getVideoSponsorTimes {
|
return 301 https://sb.ltn.fi;
|
||||||
proxy_pass http://backend_GET;
|
}
|
||||||
}
|
|
||||||
|
location /test/ {
|
||||||
location /download/ {
|
return 404 "";
|
||||||
access_log /etc/nginx/logs/download.log no_ip;
|
#proxy_pass http://localhost:4440/;
|
||||||
gzip on;
|
#proxy_pass https://sbtest.etcinit.com/;
|
||||||
gzip_types text/plain application/json;
|
}
|
||||||
#alias /home/sbadmin/sponsor/docker/database-export/;
|
|
||||||
alias /home/sbadmin/sponsor/docker/database-export/;
|
location /api/skipSegments {
|
||||||
#return 307 https://cdnsponsor.ajay.app$request_uri;
|
#return 200 "[]";
|
||||||
}
|
proxy_pass http://backend_$request_method;
|
||||||
location /database {
|
#proxy_cache CACHEZONE;
|
||||||
proxy_pass http://backend_db;
|
#proxy_cache_valid 2m;
|
||||||
#return 200 "Disabled for load reasons";
|
|
||||||
}
|
if ($request_method = POST) {
|
||||||
|
access_log /etc/nginx/logs/submissions.log user_agent;
|
||||||
location = /database.db {
|
}
|
||||||
#return 404 "Sqlite database has been replaced with csv exports at https://sponsor.ajay.app/database. Sqlite exports might come back soon, but exported at longer intervals.";
|
}
|
||||||
#alias /home/sbadmin/sponsor/databases/sponsorTimes.db;
|
|
||||||
alias /home/sbadmin/test-db/database.db;
|
location /api/getTopUsers {
|
||||||
}
|
proxy_pass http://backend_GET;
|
||||||
|
proxy_cache CACHEZONE;
|
||||||
#location = /database/sponsorTimes.csv {
|
proxy_cache_valid 20m;
|
||||||
# alias /home/sbadmin/sponsorTimes.csv;
|
}
|
||||||
#}
|
|
||||||
|
location /api/getTotalStats {
|
||||||
|
proxy_pass http://backend_GET;
|
||||||
|
#return 200 "";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/getVideoSponsorTimes {
|
||||||
|
proxy_pass http://backend_GET;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /download/ {
|
||||||
|
access_log /etc/nginx/logs/download.log no_ip;
|
||||||
|
gzip on;
|
||||||
|
gzip_types text/plain application/json;
|
||||||
|
alias /home/sbadmin/sponsor/docker/database-export/;
|
||||||
|
#return 307 https://cdnsponsor.ajay.app$request_uri;
|
||||||
|
}
|
||||||
|
location /database {
|
||||||
|
proxy_pass http://backend_db;
|
||||||
|
#return 200 "Disabled for load reasons";
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /database.db {
|
||||||
|
return 404 "Sqlite database has been replaced with csv exports at https://sponsor.ajay.app/database. Sqlite exports might come back soon, but exported at longer intervals.";
|
||||||
|
#alias /home/sbadmin/sponsor/databases/sponsorTimes.db;
|
||||||
|
#alias /home/sbadmin/test-db/database.db;
|
||||||
|
}
|
||||||
|
|
||||||
|
#location = /database/sponsorTimes.csv {
|
||||||
|
# alias /home/sbadmin/sponsorTimes.csv;
|
||||||
|
#}
|
||||||
|
|
||||||
|
#location /api/voteOnSponsorTime {
|
||||||
|
# return 200 "Success";
|
||||||
|
#}
|
||||||
|
|
||||||
|
#location /api/viewedVideoSponsorTime {
|
||||||
|
# return 200 "Success";
|
||||||
|
#}
|
||||||
|
|
||||||
#location /api/voteOnSponsorTime {
|
location /api {
|
||||||
# return 200 "Success";
|
proxy_pass http://backend_POST;
|
||||||
#}
|
}
|
||||||
|
|
||||||
#location /api/viewedVideoSponsorTime {
|
location / {
|
||||||
# return 200 "Success";
|
root /home/sbadmin/SponsorBlockSite/public-prod;
|
||||||
#}
|
}
|
||||||
|
|
||||||
location /api {
|
listen 443 default_server ssl http2; # managed by Certbot
|
||||||
proxy_pass http://backend_POST;
|
#listen 443 http3 reuseport;
|
||||||
}
|
#ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
#listen 80;
|
||||||
location / {
|
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0003/fullchain.pem; # managed by Certbot
|
||||||
root /home/sbadmin/SponsorBlockSite/public-prod;
|
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0003/privkey.pem; # managed by Certbot
|
||||||
}
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
|
||||||
listen 443 default_server ssl http2; # managed by Certbot
|
|
||||||
#listen 443 http3 reuseport;
|
|
||||||
#ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
#listen 80;
|
|
||||||
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0003/fullchain.pem; # managed by Certbot
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0003/privkey.pem; # managed by Certbot
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
server_name cdnsponsor.ajay.app;
|
|
||||||
|
|
||||||
error_page 404 /404.html;
|
|
||||||
|
|
||||||
#location /database/ {
|
|
||||||
# alias /home/sbadmin/sponsor/docker/database-export/;
|
|
||||||
#}
|
|
||||||
|
|
||||||
location /download/ {
|
|
||||||
alias /home/sbadmin/sponsor/docker/database-export/;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
server {
|
||||||
root /home/sbadmin/SponsorBlockSite/public-prod;
|
server_name cdnsponsor.ajay.app;
|
||||||
}
|
error_page 404 /404.html;
|
||||||
|
|
||||||
|
|
||||||
listen 443 ssl; # managed by Certbot
|
#location /database/ {
|
||||||
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0001/fullchain.pem; # managed by Certbot
|
# alias /home/sbadmin/sponsor/docker/database-export/;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0001/privkey.pem; # managed by Certbot
|
#}
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
#location /download/ {
|
||||||
|
# alias /home/sbadmin/sponsor/docker/database-export/;
|
||||||
|
#}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /home/sbadmin/SponsorBlockSite/public-prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
listen 443 ssl; # managed by Certbot
|
||||||
|
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0001/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0001/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
server {
|
}
|
||||||
|
|
||||||
access_log off;
|
server {
|
||||||
error_log /etc/nginx/logs/log.txt;
|
access_log off;
|
||||||
|
error_log /etc/nginx/logs/log.txt;
|
||||||
|
|
||||||
if ($host = api.sponsor.ajay.app) {
|
if ($host = api.sponsor.ajay.app) {
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
} # managed by Certbot
|
} # managed by Certbot
|
||||||
|
|
||||||
|
if ($host = sponsor.ajay.app) {
|
||||||
if ($host = sponsor.ajay.app) {
|
return 301 https://$host$request_uri;
|
||||||
return 301 https://$host$request_uri;
|
} # managed by Certbot
|
||||||
} # managed by Certbot
|
|
||||||
|
listen 80;
|
||||||
|
server_name sponsor.ajay.app api.sponsor.ajay.app;
|
||||||
listen 80;
|
return 404; # managed by Certbot
|
||||||
server_name sponsor.ajay.app api.sponsor.ajay.app;
|
}
|
||||||
return 404; # managed by Certbot
|
|
||||||
|
server {
|
||||||
|
if ($host = cdnsponsor.ajay.app) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
} # managed by Certbot
|
||||||
}
|
|
||||||
|
server_name cdnsponsor.ajay.app;
|
||||||
server {
|
listen 80;
|
||||||
if ($host = cdnsponsor.ajay.app) {
|
return 404; # managed by Certbot
|
||||||
return 301 https://$host$request_uri;
|
}
|
||||||
} # managed by Certbot
|
|
||||||
|
server {
|
||||||
|
server_name wiki.sponsor.ajay.app; # managed by Certbot
|
||||||
server_name cdnsponsor.ajay.app;
|
location / {
|
||||||
listen 80;
|
proxy_pass http://10.0.0.3:8080;
|
||||||
return 404; # managed by Certbot
|
}
|
||||||
|
|
||||||
|
listen 443 ssl http2; # managed by Certbot
|
||||||
}
|
#listen 443 http3 reuseport;
|
||||||
|
#ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
server {
|
#listen 80;
|
||||||
server_name wiki.sponsor.ajay.app; # managed by Certbot
|
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0003/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0003/privkey.pem; # managed by Certbot
|
||||||
location / {
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
proxy_pass http://10.0.0.3:8080;
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
listen 443 ssl http2; # managed by Certbot
|
|
||||||
#listen 443 http3 reuseport;
|
|
||||||
#ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
#listen 80;
|
|
||||||
ssl_certificate /etc/letsencrypt/live/sponsor.ajay.app-0003/fullchain.pem; # managed by Certbot
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/sponsor.ajay.app-0003/privkey.pem; # managed by Certbot
|
|
||||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
|
||||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
2317
package-lock.json
generated
2317
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@@ -17,35 +17,35 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ajayyy/lru-diskcache": "^1.1.9",
|
"@ajayyy/lru-diskcache": "^1.1.9",
|
||||||
"@types/request": "^2.48.6",
|
"@types/request": "^2.48.7",
|
||||||
"better-sqlite3": "^7.4.1",
|
"better-sqlite3": "^7.4.3",
|
||||||
"cron": "^1.8.2",
|
"cron": "^1.8.2",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-promise-router": "^4.1.0",
|
"express-promise-router": "^4.1.0",
|
||||||
"express-rate-limit": "^5.3.0",
|
"express-rate-limit": "^5.3.0",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"pg": "^8.6.0",
|
"pg": "^8.7.1",
|
||||||
"redis": "^3.1.2",
|
"redis": "^3.1.2",
|
||||||
"sync-mysql": "^3.0.1"
|
"sync-mysql": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/better-sqlite3": "^5.4.3",
|
"@types/better-sqlite3": "^7.4.0",
|
||||||
"@types/cron": "^1.7.3",
|
"@types/cron": "^1.7.3",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/express-rate-limit": "^5.1.3",
|
"@types/express-rate-limit": "^5.1.3",
|
||||||
"@types/mocha": "^8.2.3",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/node": "^16.3.0",
|
"@types/node": "^16.7.4",
|
||||||
"@types/node-fetch": "^2.5.11",
|
"@types/node-fetch": "^2.5.12",
|
||||||
"@types/pg": "^8.6.1",
|
"@types/pg": "^8.6.1",
|
||||||
"@types/redis": "^2.8.31",
|
"@types/redis": "^2.8.31",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.28.2",
|
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
||||||
"@typescript-eslint/parser": "^4.28.2",
|
"@typescript-eslint/parser": "^4.29.3",
|
||||||
"eslint": "^7.30.0",
|
"eslint": "^7.32.0",
|
||||||
"mocha": "^9.0.2",
|
"mocha": "^9.1.0",
|
||||||
"nodemon": "^2.0.2",
|
"nodemon": "^2.0.12",
|
||||||
"sinon": "^11.1.1",
|
"sinon": "^11.1.2",
|
||||||
"ts-mock-imports": "^1.3.7",
|
"ts-mock-imports": "^1.3.7",
|
||||||
"ts-node": "^10.0.0",
|
"ts-node": "^10.2.1",
|
||||||
"typescript": "^4.3.5"
|
"typescript": "^4.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ addDefaults(config, {
|
|||||||
userCounterURL: null,
|
userCounterURL: null,
|
||||||
newLeafURLs: null,
|
newLeafURLs: null,
|
||||||
maxRewardTimePerSegmentInSeconds: 600,
|
maxRewardTimePerSegmentInSeconds: 600,
|
||||||
|
poiMinimumStartTime: 2,
|
||||||
postgres: null,
|
postgres: null,
|
||||||
dumpDatabase: {
|
dumpDatabase: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const archiveDownvoteSegment = async (dayLimit: number, voteLimit: number
|
|||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error("Execption when insert segment in archivedSponsorTimes");
|
Logger.error("Execption when insert segment in archivedSponsorTimes");
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ export const archiveDownvoteSegment = async (dayLimit: number, voteLimit: number
|
|||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error("Execption when deleting segment in sponsorTimes");
|
Logger.error("Execption when deleting segment in sponsorTimes");
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export class Postgres implements IDatabase {
|
|||||||
await this.applyIndexes(this.config.fileNamePrefix, this.config.dbSchemaFolder);
|
await this.applyIndexes(this.config.fileNamePrefix, this.config.dbSchemaFolder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.warn("Applying indexes failed. See https://github.com/ajayyy/SponsorBlockServer/wiki/Postgres-Extensions for more information.");
|
Logger.warn("Applying indexes failed. See https://github.com/ajayyy/SponsorBlockServer/wiki/Postgres-Extensions for more information.");
|
||||||
Logger.warn(e);
|
Logger.warn(e as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function addUnlistedVideo(req: Request, res: Response): Response {
|
|||||||
const timeSubmitted = Date.now();
|
const timeSubmitted = Date.now();
|
||||||
db.prepare("run", `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted") values (?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted]);
|
db.prepare("run", `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted") values (?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ async function queueDump(): Promise<void> {
|
|||||||
|
|
||||||
lastUpdate = startTime;
|
lastUpdate = startTime;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logger.error(e);
|
Logger.error(e as string);
|
||||||
} finally {
|
} finally {
|
||||||
updateQueued = false;
|
updateQueued = false;
|
||||||
updateRunning = false;
|
updateRunning = false;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export async function getIsUserVIP(req: Request, res: Response): Promise<Respons
|
|||||||
vip: vipState,
|
vip: vipState,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export async function getLockCategories(req: Request, res: Response): Promise<Re
|
|||||||
categories
|
categories
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export async function getLockCategoriesByHash(req: Request, res: Response): Prom
|
|||||||
// merge all locks
|
// merge all locks
|
||||||
return res.send(mergeLocks(lockedRows));
|
return res.send(mergeLocks(lockedRows));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { QueryCacher } from "../utils/queryCacher";
|
|||||||
import { getReputation } from "../utils/reputation";
|
import { getReputation } from "../utils/reputation";
|
||||||
|
|
||||||
|
|
||||||
async function prepareCategorySegments(req: Request, videoID: VideoID, category: Category, segments: DBSegment[],cache: SegmentCache = {shadowHiddenSegmentIPs: {}}): Promise<Segment[]> {
|
async function prepareCategorySegments(req: Request, videoID: VideoID, category: Category, segments: DBSegment[], cache: SegmentCache = {shadowHiddenSegmentIPs: {}}): Promise<Segment[]> {
|
||||||
const shouldFilter: boolean[] = await Promise.all(segments.map(async (segment) => {
|
const shouldFilter: boolean[] = await Promise.all(segments.map(async (segment) => {
|
||||||
if (segment.votes < -1 && !segment.required) {
|
if (segment.votes < -1 && !segment.required) {
|
||||||
return false; //too untrustworthy, just ignore it
|
return false; //too untrustworthy, just ignore it
|
||||||
@@ -26,19 +26,19 @@ async function prepareCategorySegments(req: Request, videoID: VideoID, category:
|
|||||||
|
|
||||||
if (cache.shadowHiddenSegmentIPs[videoID] === undefined) cache.shadowHiddenSegmentIPs[videoID] = {};
|
if (cache.shadowHiddenSegmentIPs[videoID] === undefined) cache.shadowHiddenSegmentIPs[videoID] = {};
|
||||||
if (cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted] === undefined) {
|
if (cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted] === undefined) {
|
||||||
cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted] = await privateDB.prepare("all", 'SELECT "hashedIP" FROM "sponsorTimes" WHERE "videoID" = ? AND "timeSubmitted" = ?',
|
cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted] = await privateDB.prepare("all", 'SELECT "hashedIP" FROM "sponsorTimes" WHERE "videoID" = ? AND "timeSubmitted" = ?',
|
||||||
[videoID, segment.timeSubmitted]) as { hashedIP: HashedIP }[];
|
[videoID, segment.timeSubmitted]) as { hashedIP: HashedIP }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
//if this isn't their ip, don't send it to them
|
//if this isn't their ip, don't send it to them
|
||||||
return cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted].some((shadowHiddenSegment) => {
|
return cache.shadowHiddenSegmentIPs[videoID][segment.timeSubmitted]?.some((shadowHiddenSegment) => {
|
||||||
if (cache.userHashedIP === undefined) {
|
if (cache.userHashedIP === undefined) {
|
||||||
//hash the IP only if it's strictly necessary
|
//hash the IP only if it's strictly necessary
|
||||||
cache.userHashedIP = getHash((getIP(req) + config.globalSalt) as IPAddress);
|
cache.userHashedIP = getHash((getIP(req) + config.globalSalt) as IPAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
return shadowHiddenSegment.hashedIP === cache.userHashedIP;
|
return shadowHiddenSegment.hashedIP === cache.userHashedIP;
|
||||||
});
|
}) ?? false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const filteredSegments = segments.filter((_, index) => shouldFilter[index]);
|
const filteredSegments = segments.filter((_, index) => shouldFilter[index]);
|
||||||
@@ -80,7 +80,7 @@ async function getSegmentsByVideoID(req: Request, videoID: VideoID, categories:
|
|||||||
return segments;
|
return segments;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,10 +125,8 @@ async function getSegmentsByHash(req: Request, hashedVideoIDPrefix: VideoIDHash,
|
|||||||
|
|
||||||
return segments;
|
return segments;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err) {
|
Logger.error(err as string);
|
||||||
Logger.error(err);
|
return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export async function getUsername(req: Request, res: Response): Promise<Response
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export async function getViewsForUser(req: Request, res: Response): Promise<Resp
|
|||||||
return res.sendStatus(404);
|
return res.sendStatus(404);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export async function postLockCategories(req: Request, res: Response): Promise<s
|
|||||||
await db.prepare("run", `INSERT INTO "lockCategories" ("videoID", "userID", "category", "hashedVideoID", "reason") VALUES(?, ?, ?, ?, ?)`, [videoID, userID, category, hashedVideoID, reason]);
|
await db.prepare("run", `INSERT INTO "lockCategories" ("videoID", "userID", "category", "hashedVideoID", "reason") VALUES(?, ?, ?, ?, ?)`, [videoID, userID, category, hashedVideoID, reason]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(`Error submitting 'lockCategories' marker for category '${category}' for video '${videoID}'`);
|
Logger.error(`Error submitting 'lockCategories' marker for category '${category}' for video '${videoID}'`);
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
message: "Internal Server Error: Could not write marker to the database.",
|
message: "Internal Server Error: Could not write marker to the database.",
|
||||||
});
|
});
|
||||||
@@ -89,7 +89,7 @@ export async function postLockCategories(req: Request, res: Response): Promise<s
|
|||||||
[reason, userID, videoID, category]);
|
[reason, userID, videoID, category]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(`Error submitting 'lockCategories' marker for category '${category}' for video '${videoID}'`);
|
Logger.error(`Error submitting 'lockCategories' marker for category '${category}' for video '${videoID}'`);
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
message: "Internal Server Error: Could not write marker to the database.",
|
message: "Internal Server Error: Could not write marker to the database.",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export async function postPurgeAllSegments(req: Request, res: Response): Promise
|
|||||||
await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]);
|
await db.prepare("run", `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -390,9 +390,9 @@ async function checkEachSegmentValid(userID: string, videoID: VideoID
|
|||||||
return { pass: false, errorMessage: "One of your segments times are invalid (too short, startTime before endTime, etc.)", errorCode: 400};
|
return { pass: false, errorMessage: "One of your segments times are invalid (too short, startTime before endTime, etc.)", errorCode: 400};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for POI segments before 1 second
|
// Check for POI segments before some seconds
|
||||||
if (getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime < 1) {
|
if (!isVIP && getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime < config.poiMinimumStartTime) {
|
||||||
return { pass: false, errorMessage: "POI must be after 1 second", errorCode: 400};
|
return { pass: false, errorMessage: `POI cannot be that early`, errorCode: 400};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isVIP && segments[i].category === "sponsor" && Math.abs(startTime - endTime) < 1) {
|
if (!isVIP && segments[i].category === "sponsor" && Math.abs(startTime - endTime) < 1) {
|
||||||
@@ -684,7 +684,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<Res
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export async function setUsername(req: Request, res: Response): Promise<Response
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
Logger.error(error);
|
Logger.error(error as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ export async function setUsername(req: Request, res: Response): Promise<Response
|
|||||||
|
|
||||||
return res.sendStatus(200);
|
return res.sendStatus(200);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.sendStatus(500);
|
return res.sendStatus(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<Re
|
|||||||
}
|
}
|
||||||
return res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
|
return res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error(err);
|
Logger.error(err as string);
|
||||||
return res.status(500).json({error: "Internal error creating segment vote"});
|
return res.status(500).json({error: "Internal error creating segment vote"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,6 +106,6 @@ export interface APIVideoData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface APIVideoInfo {
|
export interface APIVideoInfo {
|
||||||
err: string | boolean,
|
err: boolean | string,
|
||||||
data?: APIVideoData
|
data?: APIVideoData
|
||||||
}
|
}
|
||||||
@@ -8,13 +8,13 @@ export function getIP(req: Request): IPAddress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (config.behindProxy as string) {
|
switch (config.behindProxy as string) {
|
||||||
case "X-Forwarded-For":
|
case "X-Forwarded-For":
|
||||||
return req.headers["x-forwarded-for"] as IPAddress;
|
return req.headers["x-forwarded-for"] as IPAddress;
|
||||||
case "Cloudflare":
|
case "Cloudflare":
|
||||||
return req.headers["cf-connecting-ip"] as IPAddress;
|
return req.headers["cf-connecting-ip"] as IPAddress;
|
||||||
case "X-Real-IP":
|
case "X-Real-IP":
|
||||||
return req.headers["x-real-ip"] as IPAddress;
|
return req.headers["x-real-ip"] as IPAddress;
|
||||||
default:
|
default:
|
||||||
return req.connection.remoteAddress as IPAddress;
|
return req.connection.remoteAddress as IPAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ export class YouTubeAPI {
|
|||||||
return { err: null, data: JSON.parse(data) };
|
return { err: null, data: JSON.parse(data) };
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { err };
|
return { err: err as string | boolean, data: null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ export class YouTubeAPI {
|
|||||||
return { err: result.statusText, data: null };
|
return { err: result.statusText, data: null };
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return {err, data: null};
|
return {err: err as string | boolean, data: null};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import { Done, getbaseURL, partialDeepEquals } from "../utils";
|
import { Done, getbaseURL } from "../utils";
|
||||||
import { db, privateDB } from "../../src/databases/databases";
|
import { db, privateDB } from "../../src/databases/databases";
|
||||||
import { getHash } from "../../src/utils/getHash";
|
import { getHash } from "../../src/utils/getHash";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
|||||||
Reference in New Issue
Block a user