1024 Commits
js ... k8s-test

Author SHA1 Message Date
Ajay
a860b89ef0 Add config for min 2022-05-27 23:23:45 -04:00
Ajay
4650316067 FIx max not being used 2022-05-27 22:46:35 -04:00
Ajay
08d458bdd6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into k8s-test 2022-05-27 19:07:53 -04:00
Ajay
0260b4889d safe navigate in user vip 2022-05-27 19:07:44 -04:00
Ajay
6abfba1b12 Add max to postgres config 2022-05-27 19:07:25 -04:00
Ajay
d038279d79 more logs 2022-05-27 12:41:09 -04:00
Ajay
35d3627760 more logs 2022-05-27 02:35:32 -04:00
Ajay
dcffb83e62 Logs for submiting 2022-05-27 01:24:34 -04:00
Ajay
a0465a44ae More logging 2022-05-26 22:59:59 -04:00
Ajay
db55d314ee Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into k8s-test 2022-05-26 22:49:27 -04:00
Ajay
6621ae3730 Fix upgrade crash 2022-05-26 22:49:21 -04:00
Ajay
b2af4fc7b0 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into k8s-test 2022-05-26 22:47:17 -04:00
Ajay
d273095525 Add improved hashed ip index 2022-05-26 22:47:07 -04:00
Ajay
4f28d92eb8 Fix params check 2022-05-26 22:21:00 -04:00
Ajay
c822a37a6e Add more logging for debugging 2022-05-26 22:15:09 -04:00
Ajay Ramachandran
5e4773afdd Merge pull request #472 from mchangrh/addl_poi_tests
add additional poi_highlight tests
2022-05-26 21:25:11 -04:00
Michael C
cbdd852566 add additional poi_highlight tests 2022-05-26 21:17:58 -04:00
Ajay
fd636a2770 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into k8s-test 2022-05-24 19:15:58 -04:00
Ajay
043c8b771e Lower redis timeout 2022-05-23 20:15:44 -04:00
Ajay
55ff3230ed Catch redis exceptions 2022-05-23 18:32:40 -04:00
Ajay
ed221c8599 Don't log 404 errors for disk cache 2022-05-21 00:39:39 -04:00
Ajay
29660d998b Don't count users for options requests 2022-05-20 16:59:21 -04:00
Ajay
f520e00ed4 Fix null values messing with env import 2022-05-20 04:53:31 -04:00
Ajay
c2e0d5a98f logs 2022-05-20 04:27:39 -04:00
Ajay
21f7d5d938 Don't add primary keys with sqlite 2022-05-17 12:53:48 -04:00
Ajay
c9a0fb7bc3 Add disk cache service
Fixes #471
2022-05-17 02:29:36 -04:00
Ajay
e79a8417f4 Don't always build backup db image 2022-05-17 01:51:11 -04:00
Ajay
dfbc32617b Create an image for db backups 2022-05-17 01:29:49 -04:00
Ajay
901a42d1b4 update docs with index 2022-05-14 15:49:08 -04:00
Ajay
634d5d083a Better indexes 2022-05-14 15:43:38 -04:00
Ajay
d67b9cdcc5 lots of anomolies 2022-05-10 14:34:22 -04:00
Ajay
78acb4a76a am wrong again 2022-05-10 14:27:43 -04:00
Ajay
5889e9e557 another id 2022-05-10 14:25:47 -04:00
Ajay
3931328b60 more duplicates 2022-05-10 14:24:34 -04:00
Ajay
f56fbbd2c7 still impossible 2022-05-10 14:22:42 -04:00
Ajay
dbfc685bf9 fix another impossible key 2022-05-10 14:21:44 -04:00
Ajay
34771e96fe change primary key for category votes 2022-05-10 14:20:07 -04:00
Ajay
bcb9e33a01 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-05-10 14:06:26 -04:00
Ajay
72de520781 Add primary keys to tables 2022-05-10 14:06:24 -04:00
Ajay Ramachandran
3c34077056 Add missing link 2022-05-10 14:05:30 -04:00
Ajay Ramachandran
2eb53015bc fix table name 2022-05-10 14:04:25 -04:00
Ajay Ramachandran
4bbaf11502 Move username logs to private 2022-05-10 13:50:41 -04:00
Ajay
60a3c017e5 Make missing folder 2022-05-06 16:21:49 -04:00
Ajay
a89abd5dd8 Rsync should also run node 2022-05-06 16:06:56 -04:00
Ajay
fc99c42e02 Run rsync build after sb server 2022-05-06 15:27:44 -04:00
Ajay
1146aac3c2 Run docker build as two jobs 2022-05-06 15:25:24 -04:00
Ajay
3341500fdf Fix docker building workflow 2022-05-06 14:42:52 -04:00
Ajay
81ad0dd640 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-05-06 14:34:26 -04:00
Ajay
ff197d2985 Add rsync docker image 2022-05-06 14:34:11 -04:00
Ajay Ramachandran
8fbb1bb79b Merge pull request #469 from mchangrh/docker-faster-build
docker build without platforms + bumped actions
2022-05-06 14:29:59 -04:00
Michael C
c0dc174f42 docker build without platforms + bumped actions 2022-05-06 13:01:53 -04:00
Ajay
d8395163b9 fix newleafurls 2022-05-06 01:53:44 -04:00
Ajay
b4b7ccec20 remove old volume 2022-05-06 00:03:01 -04:00
Ajay
d75226bde5 better db dump system 2022-05-05 22:50:07 -04:00
Ajay
db700cd7e8 Allow single newleaf url 2022-05-05 20:52:44 -04:00
Ajay Ramachandran
591e3a0051 another server 2022-05-05 09:12:12 -04:00
Ajay
b0bcf2b684 don't specify tablespace 2022-05-04 16:03:56 -04:00
Ajay
2e4b7a0c9c Don't force encoding 2022-05-04 15:36:51 -04:00
Ajay
c5f163e41e rename container 2022-05-04 02:25:29 -04:00
Ajay
c5d2cacae2 Fix postgres tests 2022-05-04 02:07:22 -04:00
Ajay
5e3e02c674 Fix context 2022-05-04 01:54:32 -04:00
Ajay
0fe85b9760 Auto build container 2022-05-04 01:51:38 -04:00
Ajay
5f53859c94 Fix docker container 2022-05-04 01:46:41 -04:00
Ajay
5b177a3e53 Prepare dockerfile for use, allow configuring via env vars 2022-05-03 22:08:44 -04:00
Ajay
a66588619a Fix rep hurting negatively voted segments 2022-05-03 15:27:23 -04:00
Ajay Ramachandran
98494aec4a more server 2022-04-27 14:19:14 -04:00
Ajay Ramachandran
e74b985304 more writes 2022-04-14 01:57:23 -04:00
Ajay
fb414ed6db Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-04-14 01:54:28 -04:00
Ajay
c7905d4062 Don't break for no response 2022-04-14 01:54:26 -04:00
Ajay Ramachandran
8a9c7c869b new server 2022-04-14 01:18:48 -04:00
Ajay Ramachandran
002298648c Merge pull request #468 from ajayyy/redis-backed-ratelimit
Back rate limit by redis and upgrade node-redis
2022-04-13 17:51:04 -04:00
Ajay
929856fd3f No ugly json access 2022-04-13 17:45:41 -04:00
Ajay
1df8117105 Fix warnings and errors 2022-04-13 17:43:38 -04:00
Ajay
146ba4ff93 Migrate breaking config changes 2022-04-13 17:41:57 -04:00
Ajay
8dc87da462 Back rate limit by redia and upgrade node-redis 2022-04-13 17:36:07 -04:00
Ajay
41c92da37e Upgrade express-rate-limit 2022-04-13 13:50:30 -04:00
Ajay
2d6be12062 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-04-11 23:48:54 -04:00
Ajay
14ef6682df Log locked downvoted segment 2022-04-11 23:48:52 -04:00
Ajay Ramachandran
10298efc08 Merge pull request #464 from mchangrh/postSkipSegment
update postSkipSegments
2022-04-11 01:56:22 -04:00
Michael M. Chang
b09ed1cbe2 Update src/routes/postSkipSegments.ts
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2022-04-11 01:54:28 -04:00
dependabot[bot]
d5611fb023 Bump moment from 2.29.1 to 2.29.2
Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.2.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.1...2.29.2)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-09 11:54:05 -04:00
Michael C
f67c0b5762 merged changes by @mini-bomba 2022-03-31 18:03:42 -04:00
Ajay Ramachandran
468ce25858 Merge pull request #465 from mini-bomba/optimize/voteOnSponsorTime
voteOnSponsorTime.ts: don't do database queries for vote eligibility on locked segments
2022-03-31 16:52:30 -04:00
Michael C
d392b1c8fc remove outdated comments & unnecessary space 2022-03-31 16:52:05 -04:00
Michael C
d02d78f325 add 80% tempVIP
- move isUserTempVIP to own file
- reduce allSegmentDuration instead of forEach
- don't return decreaseVotes from autoModerator
- completely skip autoModCheck if VIP
2022-03-31 16:43:10 -04:00
mini-bomba
6b5dc54cc7 voteOnSponsorTime.ts: don't do database queries for vote eligibility on locked segments 2022-03-31 22:41:09 +02:00
Michael C
76cc603a3f update auotmod check
- remove NB code
- reduce complexity + unnecessary iterations
- use client duration if given
2022-03-31 16:02:50 -04:00
Ajay
fe0afd58bc Save userid with votes 2022-03-30 16:02:30 -04:00
Ajay
9bcf7ed199 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-03-30 15:43:54 -04:00
Ajay
fafcbe0b25 Move new user down 2022-03-30 15:43:53 -04:00
Ajay Ramachandran
4c2b258038 new server 2022-03-30 14:15:44 -04:00
Ajay Ramachandran
bd059c3a68 another get query 2022-03-29 14:14:53 -04:00
Ajay Ramachandran
70a507818f move post server again 2022-03-29 13:08:12 -04:00
Ajay Ramachandran
5f4f45056e Increase max memory 2022-03-28 12:18:15 -04:00
Ajay Ramachandran
7ead3ddc63 reenable redis snapshots 2022-03-28 12:17:37 -04:00
Ajay Ramachandran
a536e4aeb8 remove 10s cache 2022-03-28 12:07:46 -04:00
Ajay Ramachandran
2b237a4a8b Move server 2022-03-28 11:58:59 -04:00
Ajay Ramachandran
03542ebcac Merge pull request #460 from ajayyy/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-03-24 11:38:59 -04:00
dependabot[bot]
b3c2b2c15d Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-24 07:12:26 +00:00
Ajay Ramachandran
80e3a55cfe Change url for test 2022-03-17 12:31:09 -04:00
Ajay Ramachandran
9224960dea Fix wiki redirect 2022-03-17 12:30:00 -04:00
Ajay
84ea08d6d0 Fix crash when categories array is broken 2022-03-11 10:19:55 -05:00
Ajay Ramachandran
e9c43a22f5 Don't redirect to different port 2022-03-08 13:28:59 -05:00
Ajay Ramachandran
fe6d2e88bd Increase read timeout 2022-03-07 16:45:31 -05:00
Ajay Ramachandran
0bb6d29932 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-03-07 18:40:17 +01:00
Ajay Ramachandran
e9ebf08984 proxy protocol 2022-03-07 18:39:38 +01:00
Ajay
f156a5fbe9 Don't count low viewed downvoted segments 2022-03-06 18:42:24 -05:00
Ajay
b182945274 Clear redis timeouts 2022-03-04 19:22:01 -05:00
Ajay
6507a3a68d Add timeout to redis calls 2022-03-04 19:19:15 -05:00
Ajay Ramachandran
e8b8b87190 lower timeout 2022-03-04 02:29:52 -05:00
Ajay
c602285102 Fix wrong timeout variable being used 2022-03-03 20:09:30 -05:00
Ajay
744b5ea4f6 Increase max fails, lower timeout 2022-03-03 19:58:03 -05:00
Ajay Ramachandran
68b2fba24c Update nginx config 2022-03-04 01:53:31 +01:00
Ajay
dbb8128a3a Improve useragent parsing 2022-02-22 00:51:45 -05:00
Ajay
22b4135d62 Fix flaky test 2022-02-21 22:58:23 -05:00
Ajay
4029b15233 Add query cache for shadowban 2022-02-21 22:46:13 -05:00
Ajay
90fc02e340 Better private db index 2022-02-21 21:57:57 -05:00
Ajay
6b1fa7f5d0 15 second timeout for requests 2022-02-19 16:02:05 -05:00
Ajay Ramachandran
0e8b6eb506 Update nginx config 2022-02-16 02:27:04 +01:00
Ajay Ramachandran
50d8c5f105 Merge pull request #457 from mchangrh/highlight_poi
force poi_highlight to be type POI
2022-02-13 16:40:20 -05:00
Michael C
4da3c2d049 force poi_highlight to be type POI 2022-02-13 16:13:03 -05:00
Ajay
a3ddbef38e Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-02-12 13:11:47 -05:00
Ajay
77a1799a7f Filter input 2022-02-12 13:11:46 -05:00
Ajay Ramachandran
0dbd081063 Update nginx config 2022-02-12 06:49:21 +01:00
Ajay
c9b18a4938 Don't fail if no latest submission with video duration 2022-02-12 00:06:46 -05:00
Ajay
155c5a9b97 Don't allow upvoting dead locked category segment
for full video
2022-02-12 00:05:01 -05:00
Ajay
1bc9a69b79 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-02-11 12:06:33 -05:00
Ajay
fb6e98f93f Don't allow changing highlight category 2022-02-11 12:05:04 -05:00
Ajay Ramachandran
61eb2e665b Merge pull request #451 from mchangrh/voteOnSponsorTime
rewrite voteOnSponsorTimes
2022-02-10 23:02:35 -05:00
Ajay Ramachandran
de7b985535 Merge branch 'master' into voteOnSponsorTime 2022-02-10 23:00:51 -05:00
Ajay Ramachandran
bbcbd3783a Merge pull request #449 from mchangrh/fixFullLocks
add full video and exclusive_access support
2022-02-10 22:13:14 -05:00
Ajay Ramachandran
6db9404e1c Merge pull request #456 from ajayyy/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.5 to 1.14.8
2022-02-10 20:22:12 -05:00
dependabot[bot]
857ee04c3c Bump follow-redirects from 1.14.5 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.5 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.5...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-11 01:21:14 +00:00
Ajay Ramachandran
8b58d52b12 Merge pull request #450 from ajayyy/dependabot/npm_and_yarn/simple-get-4.0.1
Bump simple-get from 4.0.0 to 4.0.1
2022-02-10 20:20:34 -05:00
Ajay
50fab971e0 Temp vip fix 2022-02-10 19:42:08 -05:00
Michael C
df6c76ede9 quote for postgres 2022-02-04 00:43:20 -05:00
Michael C
0ff38b918b fix tests, add add actionType tests 2022-02-04 00:40:13 -05:00
Michael C
5713b96d13 add test for downvote videoDuration change 2022-02-04 00:21:15 -05:00
Michael C
f3d10bd19f don't leak adminID on tempVIP 2022-02-03 21:31:43 -05:00
Michael C
a2f2cf9c0d update lockCategories
- migration to remove invalid locks
- lockCategories poi_highlight is now actionType poi
- deleteLockCategories now takes actionType
- update postLockCategories response, serverside filtering for accepted categories
- fix tests accordingly
2022-02-03 17:44:29 -05:00
Michael C
2b8944bf15 correct tempVIP test 2022-02-03 13:51:15 -05:00
Michael C
db5922e4b7 fix tempvip cases 2022-02-03 13:49:13 -05:00
Michael C
0854ad1f65 rewrite voteOnSponsorTimes 2022-02-03 06:06:54 -05:00
dependabot[bot]
75cf14a960 Bump simple-get from 4.0.0 to 4.0.1
Bumps [simple-get](https://github.com/feross/simple-get) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/feross/simple-get/releases)
- [Commits](https://github.com/feross/simple-get/compare/v4.0.0...v4.0.1)

---
updated-dependencies:
- dependency-name: simple-get
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-29 00:04:08 +00:00
Ajay
985039a86b Fix segments always coming back as skip 2022-01-20 19:07:34 -05:00
Ajay
acc983b829 Downgrade redis 2022-01-20 15:57:31 -05:00
Ajay
ae6255cc69 Add timeout to newleaf 2022-01-20 15:36:38 -05:00
Michael C
830fdff3be add full video and exclusive_access support 2022-01-19 21:53:40 -05:00
Ajay Ramachandran
c2516461ad Merge pull request #448 from ajayyy/poi-highlight
Highlight category now has it's own action type
2022-01-19 19:34:35 -05:00
Ajay
d367998d39 Remove use of "CategoryActionType" 2022-01-19 18:11:01 -05:00
Ajay
6ece944536 Highlight category now has it's own action type 2022-01-19 17:48:09 -05:00
Ajay
5413d8dc9c Ignore full video for reputation 2022-01-17 12:34:51 -05:00
Ajay
5aa78967de Add nice error page to homepage 2022-01-16 18:18:46 -05:00
Ajay
50d0cbd378 Fix error conf redirecting to wrong url 2022-01-16 18:18:37 -05:00
Ajay
8759f8dbf2 Use object for merging locks
Co-authored-by: Nishant Arora <whizzzkid@users.noreply.github.com>
2022-01-16 15:17:36 -05:00
Ajay
acb5a9467e Fix warning 2022-01-16 15:03:46 -05:00
Ajay
a31a4d016f Fix lock reason test 2022-01-16 13:19:42 -05:00
Ajay Ramachandran
b39d323a22 Merge pull request #444 from mchangrh/full-tests
Tests for full video locks
2022-01-16 13:17:19 -05:00
Ajay Ramachandran
bfd017a66a formatting 2022-01-16 13:16:13 -05:00
Ajay Ramachandran
72bbc79943 Fix syntax 2022-01-16 13:10:14 -05:00
Ajay Ramachandran
677e05e46c Merge pull request #442 from mchangrh/nginx-update
update nginx configs
2022-01-16 13:04:35 -05:00
Ajay Ramachandran
732eeed41d Update nginx config 2022-01-16 19:03:02 +01:00
Ajay Ramachandran
ea196e84f1 Merge pull request #439 from mchangrh/channelVipTests
additional tests for tempVIP
2022-01-16 12:54:22 -05:00
Ajay
df23d1510d More friendly lock message 2022-01-15 15:41:39 -05:00
Ajay
76bfd27b33 Add exclusive access category 2022-01-14 00:23:09 -05:00
Ajay
6fe7200481 don't allow category vote for full video segment 2022-01-14 00:21:13 -05:00
Michael C
6f737ab0b6 minor typo spotted 2022-01-08 17:16:23 -05:00
Michael C
ea4adc0e14 getLockCategories + lint 2022-01-07 18:12:20 -05:00
Michael C
6ec80df8f4 update getLockReason 2022-01-07 03:04:47 -05:00
Ajay Ramachandran
762f4f6964 Merge pull request #445 from HaiDang666/substr-deprecated
remove deprecated method: String.substr
2022-01-07 02:19:05 -05:00
Haidang666
a1b59cba34 remove deprecated method: String.substr 2022-01-07 13:59:47 +07:00
Michael C
0584492b8c getLockCategories 2022-01-06 23:56:27 -05:00
Michael C
77de17c810 add allow-headers content-type 2022-01-06 21:31:34 -05:00
Ajay Ramachandran
9ca01407e8 Fix typo 2022-01-06 20:26:33 -05:00
Michael C
7472af714a missing semicolons 2022-01-06 18:49:49 -05:00
Michael C
164a9dab17 refactored nginx configs
- handle CORS within nginx
- remove allow-headers from CORS
- add custom dynamic error pages
- remove unused fastcgi
- removed OPTIONS backend
- remove previous custom errorDirective
- moved proxy directives to appropiate file
2022-01-06 18:42:48 -05:00
Ajay Ramachandran
b2e37804f5 Merge pull request #440 from ajayyy/full-video-labels
Full video labeling
2022-01-06 15:55:11 -05:00
Ajay
cb9b2ff965 Fix test data using wrong hash 2022-01-06 15:28:44 -05:00
Ajay
ad4c34ef28 Fix UUID test 2022-01-06 15:20:41 -05:00
Ajay
c0c2b365ae Fix full video different category duplicate error 2022-01-06 15:17:21 -05:00
Ajay
77565d7eda Fix wrong array being returned for highlight and full video segments 2022-01-06 15:17:01 -05:00
Ajay
75cad434b6 Fix unlocked segments being ignored 2022-01-06 14:58:46 -05:00
Ajay
be441a314f Fix locked segment filtering for highlight and full video 2022-01-06 14:54:27 -05:00
Ajay
d5d73273de Don't autohide full video segments for duration change 2022-01-06 14:45:05 -05:00
Ajay
44ffa40b6c Should not add full segments to db from shadowbanned users 2022-01-06 14:15:50 -05:00
Ajay
b4f8bdd719 Add test for submitting full video converting to upvote 2022-01-06 14:10:41 -05:00
Ajay
68c6266139 formatting 2022-01-06 03:40:04 -05:00
Ajay
65954520d0 Treat duplicate full video submission as upvote 2022-01-06 03:39:46 -05:00
Ajay
da03958e97 Lock docker dependency versions 2022-01-06 01:45:52 -05:00
Ajay
f89bef74d6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2022-01-04 20:39:53 -05:00
Ajay
6a98a215ac Don't group different categories 2022-01-04 20:39:50 -05:00
Ajay
89ea13956a Ensure only one full video label is served 2022-01-04 19:27:50 -05:00
Ajay Ramachandran
f86d2ab0e4 Merge pull request #441 from mchangrh/cache-getTopUsers
[nginx] add getTopCategoryUsers to CACHEZONE
2022-01-02 22:49:01 -05:00
Ajay
8fef35dbbc Allow submitting full sponsors and selfpromo 2022-01-02 22:38:06 -05:00
Michael C
8a80b97e8c add getTopCategoryUsers to CACHEZONE 2022-01-02 22:28:22 -05:00
Ajay
7f7cc3a7ca Increase required overlap for same category and action type 2022-01-02 14:02:26 -05:00
Ajay
09eec5a4a5 Add locking by action type 2022-01-02 14:00:54 -05:00
Michael C
05516a5d7d fix postgres quotes & fixed test.json 2021-12-31 17:12:46 -05:00
Michael C
a42f023074 add more testing, change enabled
- add 404 if channelID cannot be dervived
- added response message on success returning channel name
- test limits of temp VIP
- minor eslint
2021-12-31 16:54:28 -05:00
Ajay Ramachandran
aaa3179d42 Merge pull request #435 from mchangrh/categoryLeaderboards
add getTopCategoryUsers
2021-12-31 14:06:34 -05:00
Ajay Ramachandran
ce4270b96d Merge branch 'master' into categoryLeaderboards 2021-12-31 14:04:20 -05:00
Ajay Ramachandran
df3d6fe9c7 Merge pull request #438 from mchangrh/tempVIP
channel-specific VIP
2021-12-31 14:02:05 -05:00
Ajay Ramachandran
dd900497f4 Merge pull request #437 from mchangrh/redis-track-status
add redis status/min
2021-12-31 14:01:20 -05:00
Michael C
a1d28fbfe1 add addUserAsTempVIP 2021-12-31 04:26:37 -05:00
Michael C
9ae16ea9b6 add tempVIP check to vote 2021-12-30 22:21:27 -05:00
Michael C
b9a620fc3b add redis status/min 2021-12-30 16:47:11 -05:00
Michael C
42624a7782 minor eslint fixes 2021-12-30 04:09:46 -05:00
Michael C
f97af4c433 texts for getTopCategoryUsers 2021-12-30 04:07:38 -05:00
Michael C
98994cee01 add getTopUsers test 2021-12-30 04:07:21 -05:00
Michael C
90f891aee4 arr.push instead of add at index 2021-12-30 03:13:55 -05:00
Ajay Ramachandran
ceabeefe21 disable logging again 2021-12-29 23:33:00 +01:00
Ajay
00d7e1f058 Force skip segments cache clear 2021-12-29 00:22:02 -05:00
Ajay
13a4bc3ee9 Fix tests 2021-12-29 00:19:53 -05:00
Ajay
939ec61c0e Increase threshold for category overlap 2021-12-29 00:18:07 -05:00
Michael C
0db3240f58 add getTopCategoryUsers 2021-12-27 04:58:11 -05:00
Ajay Ramachandran
11a1bbc866 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-12-22 23:26:37 +01:00
Ajay Ramachandran
3e3f7c2972 Fix database downloads 2021-12-22 23:26:04 +01:00
Ajay
95d14c0fdb Allow overlaping non music with other categories 2021-12-21 11:21:19 -05:00
Ajay
7b2d9365a0 Fix undefined issue 2021-12-20 23:52:24 -05:00
Ajay Ramachandran
1c304b636f Merge pull request #430 from mchangrh/filler
add filler to userStats and getTopUsers
2021-12-20 23:44:24 -05:00
Ajay Ramachandran
4e94cdda72 Merge pull request #432 from mchangrh/eslint-and-workflow
eslint + workflow formatting
2021-12-20 23:44:09 -05:00
Ajay Ramachandran
dfe669a0cd Merge pull request #431 from ajayyy/cached-get-segments
Add overlapping group caching + filter out identical segments of different categories
2021-12-20 23:44:03 -05:00
Ajay
873551e1c4 formatting fix 2021-12-20 23:39:58 -05:00
Ajay
66af4f60c8 Add test for different categories at same time 2021-12-20 23:07:12 -05:00
Michael C
3dd9024cc7 eslint + workflow formatting
- appropriate job names
- only trigger on pushes to master branch & PRs
- conform to formatting
2021-12-20 23:04:41 -05:00
Ajay
5ebb638925 Add overlapping group caching 2021-12-20 22:51:47 -05:00
Ajay Ramachandran
7aa9524835 Merge pull request #429 from mchangrh/redis-test
add redis tests
2021-12-20 22:50:21 -05:00
Ajay Ramachandran
f6d68bb3f3 Merge pull request #421 from HaiDang666/392_getSearchSegments-pagination
add custom pagination in getSearchSegments
2021-12-20 22:36:22 -05:00
Ajay Ramachandran
7caaf833dd Fix safe navigation 2021-12-20 22:29:48 -05:00
Ajay
a137f8a434 Add redis to ci name 2021-12-20 22:27:35 -05:00
Michael C
2ee7c82760 add test for filer 2021-12-20 00:27:38 -05:00
Michael C
b730383293 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into filler 2021-12-20 00:27:09 -05:00
Michael C
d1ed4376ef add filler to userStats and getTopUsers 2021-12-20 00:19:14 -05:00
Ajay Ramachandran
f54b9f7ae1 Fix nginx config issues 2021-12-20 03:24:54 +01:00
Ajay Ramachandran
9d1a401e3e Merge pull request #426 from mchangrh/tune-nginx
nginx tuning in lieu of http/2
2021-12-19 21:15:55 -05:00
Ajay Ramachandran
4fa4fdf1e3 Update nginx config 2021-12-20 03:13:29 +01:00
Ajay Ramachandran
5a358caedb Merge pull request #419 from mchangrh/patch-1
[searchSegments] ignore if votes <= -2
2021-12-19 21:00:45 -05:00
Ajay Ramachandran
e2e4f79cec Merge pull request #428 from mchangrh/userNameRows
remove empty rows from userNames
2021-12-19 21:00:27 -05:00
Michael C
ed44eaffec Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into redis-test 2021-12-19 19:38:55 -05:00
Michael C
1f9dc92074 add arrayDeepPartialEquals 2021-12-19 19:37:22 -05:00
Ajay Ramachandran
0f4b0c2f54 formatting 2021-12-19 19:13:49 -05:00
Michael C
68bc6469ce add redis tests 2021-12-19 02:03:50 -05:00
Ajay Ramachandran
d7e86aac80 Merge pull request #427 from mchangrh/fix-test-422
remove extra print from test
2021-12-19 01:08:02 -05:00
Haidang666
89a83f78cc add more test on limit, page 2021-12-19 10:13:06 +07:00
Michael C
544af7ce15 remove empty rows from userNames 2021-12-18 21:33:38 -05:00
Michael C
ba07137933 remove extra print from test 2021-12-18 20:53:17 -05:00
Michael C
e0bf2afdc9 nginx tuning
- whitespace formatting
- added keepalive
- buffer access_logs
friendship ended with http/2, nginx is my new best friend
2021-12-18 18:59:24 -05:00
Haidang666
ec73ae309e add custom pagination in getSearchSegments 2021-12-17 15:08:51 +07:00
Ajay Ramachandran
caf94a7a93 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-12-12 23:35:13 -05:00
Ajay Ramachandran
4092ce2616 Fix async causing shadow banned segments to always appear 2021-12-12 23:35:10 -05:00
Ajay Ramachandran
14c2f16cb6 update nginx config 2021-12-13 01:41:16 +01:00
Ajay Ramachandran
a0720329d0 Write to private db first when rating 2021-12-12 00:55:22 -05:00
Michael C
292b05443f ignored segments should exclude downvote 2021-12-10 16:40:34 -05:00
Michael M. Chang
98cb2b022d [searchSegments] ignore if votes <= -2
the ignored parameter should also ignore segments that are downvoted
2021-12-10 07:52:47 -05:00
Ajay Ramachandran
6f3b45bdbd Update nginx config 2021-12-05 05:06:31 +01:00
Ajay Ramachandran
4964c72e71 Serve database csv from node 2021-12-04 22:55:36 -05:00
Ajay Ramachandran
e3042f7623 Add limit to bulk hash prefix 2021-12-04 22:34:50 -05:00
Ajay Ramachandran
edd11cc99c Merge pull request #409 from mchangrh/redisHashCache
getHash redis cache
2021-12-03 00:14:01 -05:00
Ajay Ramachandran
8d533d0e94 Move default hash times to var 2021-12-03 00:12:08 -05:00
Ajay Ramachandran
8f3a5a0e4d Merge pull request #416 from mchangrh/npm-update
bump dependencies, npm audit fix
2021-12-03 00:02:16 -05:00
Ajay Ramachandran
bd3e38fe40 Remove extra log 2021-12-02 23:48:10 -05:00
Ajay Ramachandran
6f05b5b92d Merge pull request #412 from mchangrh/requiredSegment/shortHash
get requiredSegments by partial hash
2021-12-02 23:44:29 -05:00
Ajay Ramachandran
9bc65d566a Merge pull request #417 from ajayyy/bulk-ratings
Add bulk rating fetching
2021-12-02 23:44:09 -05:00
Ajay Ramachandran
0cd25f0498 Fix issues with query caching for ratings 2021-12-02 23:42:39 -05:00
Ajay Ramachandran
48ac8d1136 Add test for get bulk rating 2021-12-02 23:12:48 -05:00
Ajay Ramachandran
dd2db4bbbf Fix wrong eslint disable 2021-12-02 01:25:26 -05:00
Ajay Ramachandran
9e86f463d8 Support regex via sqlite 2021-12-02 01:23:59 -05:00
Ajay Ramachandran
733bd338e7 Add bulk rating fetching 2021-12-02 01:10:09 -05:00
Michael C
7df9f0b054 npm audit fix 2021-12-01 16:45:11 -05:00
Michael C
91ba6948d8 engine limited by express-promise-router, dev engine is LTS 16 2021-12-01 16:26:56 -05:00
Michael C
af4b2e4624 minor changes 2021-12-01 15:43:43 -05:00
Michael C
8fe0a45435 add partial lookup 2021-11-30 18:58:37 -05:00
Ajay Ramachandran
d55a860114 Merge pull request #406 from mchangrh/searchSegments/userID
add userID to searchSegments
2021-11-28 11:20:14 -05:00
Ajay Ramachandran
ad23ec040b Merge pull request #405 from mchangrh/validateVideoID
add check for zero length videoID
2021-11-28 11:20:04 -05:00
Michael C
5a69de730c rename hashKey to be more generic 2021-11-27 02:47:18 -05:00
Michael C
6baa00b76d remove newline-before-return eslint 2021-11-27 02:42:59 -05:00
Michael C
a5a90e3c84 add getHashCache where applicable= 2021-11-27 02:41:34 -05:00
Ajay Ramachandran
7e1550f3c0 Update nginx config 2021-11-21 17:40:39 +01:00
Michael C
4584dbc047 add userID to searchSegments 2021-11-20 01:15:33 -05:00
Michael C
0a869dbbd7 strict check for videoID length 2021-11-19 02:27:42 -05:00
Ajay Ramachandran
20e9a3e8b1 Fix index using non existent column 2021-11-16 22:53:59 -05:00
Ajay Ramachandran
0478491f93 Merge pull request #390 from whizzzkid/fix/general-fixes
General Improvements
2021-11-16 19:22:52 -05:00
Ajay Ramachandran
4797a7d938 Merge branch 'master' into fix/general-fixes 2021-11-16 19:18:16 -05:00
Ajay Ramachandran
726a081df1 Merge pull request #403 from mchangrh/ratingFix
Fixed issues with ratings
2021-11-16 19:17:48 -05:00
Michael C
ad7574308f clear rating cache 2021-11-15 01:50:09 -05:00
Michael C
03c95ca158 rename clearSegmentCache 2021-11-15 01:48:14 -05:00
Michael C
b9ebd00365 fixed tests, typos and optimized code for ratings 2021-11-15 01:17:36 -05:00
Ajay Ramachandran
bc6db0d109 Add endpoints for rating endpoint (dislikes)
https://github.com/ajayyy/SponsorBlock/issues/1039
2021-11-14 23:09:12 -05:00
Ajay Ramachandran
7590047c6d Merge pull request #401 from ajayyy/chapters
Initial Chapters
2021-11-14 16:41:51 -05:00
Ajay Ramachandran
e85a0d4f28 Fix lock reason test with filler 2021-11-08 19:28:27 -05:00
Ajay Ramachandran
16c5819f5c Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into chapters 2021-11-08 19:26:39 -05:00
Ajay Ramachandran
db48953e39 Allow mute intro, outro, preview and add filler 2021-11-08 19:24:58 -05:00
Ajay Ramachandran
1106048b37 Allow mute intro, outro, preview and add filler 2021-11-08 19:22:17 -05:00
Ajay Ramachandran
a2698fb70d Set all videoInfo values in chapters name test 2021-11-06 23:18:28 -04:00
Ajay Ramachandran
6919b5433b Add suggested chapter names 2021-11-06 22:43:03 -04:00
Ajay Ramachandran
c371d35e82 update db schema 2021-11-06 19:56:01 -04:00
Ajay Ramachandran
0b7904f891 Add test case for small part that is the same action type 2021-11-06 17:40:26 -04:00
Ajay Ramachandran
c0072d5c72 Add another segment to overlap test case and fix for that case 2021-11-06 17:28:58 -04:00
Ajay Ramachandran
2733cd6606 Switch to new method that splits up existing groups instead of making new ones
Kind of #107
2021-11-06 16:11:02 -04:00
Ajay Ramachandran
7eef74a7dc Add new % overlap function used for chapters
Kind of #107
2021-11-06 16:09:55 -04:00
Ajay Ramachandran
32150e4a1d Add submitting description for chapters 2021-11-06 00:54:28 -04:00
Ajay Ramachandran
0c16448065 Merge pull request #397 from mchangrh/base-sqlite-ci
add generate-sqlite-base
2021-10-30 21:50:55 -04:00
Ajay Ramachandran
991d384f11 Merge pull request #398 from mchangrh/userID-skipSegments
add userID to getSkipSegments
2021-10-30 21:50:32 -04:00
Ajay Ramachandran
aa40ac7777 Merge pull request #400 from mchangrh/shadowban-test
add tests for shadowban
2021-10-30 20:04:02 -04:00
Michael C
88a368d0b9 add tests for shadowban 2021-10-30 17:58:17 -04:00
Nishant Arora
246ec7c3c3 Merge branch 'master' into fix/general-fixes 2021-10-27 23:51:45 -06:00
Nishant Arora
70d0387356 routes/deleteLockCategories: fixed 2021-10-27 23:50:20 -06:00
Ajay Ramachandran
19f7bbcde5 Add info about using sb mirror
Closes #373
2021-10-27 21:25:46 -04:00
Ajay Ramachandran
dd8b2f8809 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-10-27 19:36:36 -04:00
Ajay Ramachandran
6cf268330f Remove old auto-ban on low trust 2021-10-27 19:36:33 -04:00
Michael C
9d761815d8 add userID to getSkipSegments 2021-10-27 17:03:16 -04:00
Michael C
6adfb84c0f add generate-sqlite-base 2021-10-27 16:04:52 -04:00
Ajay Ramachandran
d0b1608181 Merge pull request #396 from mchangrh/fix-rsync
fix rsync config name
2021-10-27 09:04:31 -04:00
Michael C
dc7831c31f fix rsync file name 2021-10-26 22:38:46 -04:00
Ajay Ramachandran
06af78c770 Merge pull request #394 from mchangrh/rsync-container
add rsyncd config
2021-10-26 22:16:06 -04:00
Ajay Ramachandran
58de2a786d Fix testing server getting full path 2021-10-26 22:05:51 -04:00
Ajay Ramachandran
452d8a47f5 Switch testing server ip 2021-10-26 22:02:50 -04:00
Ajay Ramachandran
6db89778a9 enable testing server 2021-10-26 22:00:32 -04:00
Michael C
65fa663a1a add rsyncd config 2021-10-26 21:55:32 -04:00
Ajay Ramachandran
59b1d02075 Add new vps 2021-10-26 20:54:25 -04:00
Ajay Ramachandran
cfae20282f Merge pull request #377 from mchangrh/nginx-gzip
Fix NGINX mime type
2021-10-26 20:52:29 -04:00
Ajay Ramachandran
d06762418e Merge pull request #387 from mchangrh/no-console
[ESLint] noconsole
2021-10-26 20:39:43 -04:00
Michael C
a9adfbc06d disable eslint for error dump 2021-10-26 20:37:49 -04:00
Michael C
5743ed5434 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into no-console 2021-10-26 20:36:53 -04:00
Ajay Ramachandran
eecb238e18 Merge pull request #389 from mchangrh/replication-mirror
changes for mirror mode
2021-10-26 20:34:22 -04:00
Ajay Ramachandran
3877cd580c Merge pull request #391 from HaiDang666/388_lock-user-with-reason
add username in get lock reason route
2021-10-26 20:26:44 -04:00
Ajay Ramachandran
393027c1ea Merge pull request #386 from mchangrh/more-stats
add loadAvg to status
2021-10-26 20:24:06 -04:00
Michael C
6be034362b don't queue dump if generate=false 2021-10-24 16:19:40 -04:00
Felix Hoang
103280ca59 remove unuse variable 2021-10-24 16:27:12 +07:00
Felix Hoang
b715b30ae6 add username in get lock reason route 2021-10-24 16:04:18 +07:00
Michael C
6bcc4cdfa3 sturcture for init and exit 2021-10-22 11:37:32 -04:00
Michael C
a3ea732870 delete config.json.backup - thankfully no private information 2021-10-22 03:54:17 -04:00
Michael C
fd6ae8fc0e bargaining with postgres CI
- fix tests with lockCategories
- new unique naming scheme for video
- super janky somehow working method for comparing arrays out of order
2021-10-22 03:53:27 -04:00
Nishant Arora
0a54b18d64 Making newline as warning 2021-10-22 00:32:43 -06:00
Nishant Arora
05072f5d22 routes/deleteLockCategories: Run Queries in Parallel 2021-10-22 00:17:43 -06:00
Nishant Arora
28dc0fb512 routes/addUserAsVIP: fixed 2021-10-21 23:59:08 -06:00
Nishant Arora
2376d88481 routes/addUnlistedVideo: Improved 2021-10-21 23:49:42 -06:00
Nishant Arora
db8543a0b4 utils/getService: Improve Functionality to run on O(n) 2021-10-21 23:49:36 -06:00
Nishant Arora
b785658db1 Fixing eslint 2021-10-21 23:48:35 -06:00
Michael C
2d10dd6c9c add extension to db.sql 2021-10-22 01:05:08 -04:00
Michael C
c6428bf9e4 import without fs 2021-10-21 23:15:36 -04:00
Michael C
0163a52e55 if in mirror mode, import CSV files 2021-10-21 03:49:25 -04:00
Michael C
815df94db4 add eslint rule for no-console 2021-10-20 01:01:58 -04:00
Michael C
109578a3ed remove extra console.log lines 2021-10-20 00:59:08 -04:00
Michael C
ac15686b47 add loadAvg to status 2021-10-20 00:16:27 -04:00
Ajay Ramachandran
93536976d0 Merge pull request #385 from mchangrh/384-fix
Implement #384
2021-10-19 23:30:09 -04:00
Michael C
6caab2ef06 don't destructure and re-structure 2021-10-19 23:23:58 -04:00
Michael C
a316403bb5 quote for postgres 2021-10-19 23:22:13 -04:00
Michael C
5cf7a61de1 restructure for postgres 2021-10-19 23:14:52 -04:00
Michael C
d0deb6fe27 finish tests and remove extra console.logs 2021-10-19 23:06:47 -04:00
Michael C
4ee35d3cd4 implementation 2021-10-19 22:05:08 -04:00
Ajay Ramachandran
ec16828497 Merge pull request #383 from mchangrh/fix-fragment
fix fragment in links
2021-10-19 21:33:40 -04:00
Michael C
83b8127eb2 fix fragment in links 2021-10-19 03:52:24 -04:00
Ajay Ramachandran
a42e933240 Send webhook link with required segment 2021-10-18 20:02:17 -04:00
Ajay Ramachandran
201f6cb900 update lru diskcache 2021-10-17 16:32:07 -04:00
Ajay Ramachandran
c91d04760a Add documentation for video info db schema 2021-10-17 14:57:55 -04:00
Ajay Ramachandran
91c52c15fd Add indexes for videoInfo 2021-10-17 14:55:55 -04:00
Ajay Ramachandran
c6944bd7cf Fix types on videoInfo table 2021-10-17 14:54:35 -04:00
Ajay Ramachandran
450f4a2d44 Store video info from submissions 2021-10-17 14:42:48 -04:00
Ajay Ramachandran
bda2ff4d23 Merge pull request #380 from ajayyy/skipSegments-values
Return locked and votes in skipSegment calls
2021-10-15 00:17:10 -04:00
Ajay Ramachandran
f6d6e93847 Return locked and votes in skipSegment calls
#379
2021-10-15 00:14:59 -04:00
Ajay Ramachandran
9cdccbe7f0 Fix user counter not working 2021-10-12 21:19:37 -04:00
Michael C
2ad52e70bb enforce gzip for downloads 2021-10-05 23:31:05 -04:00
Ajay Ramachandran
656e35c080 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-10-03 21:16:10 +02:00
Ajay Ramachandran
895df94493 Add redirect to shorturl for wiki 2021-10-03 21:16:05 +02:00
Ajay Ramachandran
8d07ba7f23 Merge pull request #376 from FlorianZahn/votingAbuseFixes
Voting abuse fixes
2021-10-03 13:21:11 -04:00
Ajay Ramachandran
7e23bc9eeb Check for service in category vote 2021-10-03 13:12:14 -04:00
Ajay Ramachandran
658e391f50 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into pr/FlorianZahn/376 2021-10-03 13:11:25 -04:00
FlorianZahn
69e321c405 Improved formatting 2021-10-03 19:03:49 +02:00
Ajay Ramachandran
b5d9c02d9e Merge pull request #374 from HaiDang666/355_check-service
add service to table only have videoID
2021-10-03 12:57:28 -04:00
Ajay Ramachandran
2388dea859 Remove extra log 2021-10-03 12:55:49 -04:00
FlorianZahn
178c4d9792 Remove comment
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-10-03 18:53:34 +02:00
FlorianZahn
0aa286442f Vip locked segment voting, handle client side
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-10-03 18:53:06 +02:00
Ajay Ramachandran
543fb535df Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-10-03 08:56:42 +02:00
Ajay Ramachandran
9cb0b356ed Kill dead nginx processes to avoid memory leak #372 2021-10-03 08:56:02 +02:00
FlorianZahn
7135aa3369 removing console.log() commands 2021-10-02 05:11:26 +02:00
FlorianZahn
aacd297b3b Fixed bugs where normal users could cirumvent vip locks by changing categories 2021-10-02 05:04:18 +02:00
FlorianZahn
bb2a007ed1 first changes and timeout on 2nd test 2021-10-02 04:39:54 +02:00
Haidang666
356974b478 add service to table only have videoID 2021-09-30 13:56:55 +07:00
Ajay Ramachandran
99d72b92e4 Clear cache after purging segments 2021-09-29 16:31:44 -04:00
Ajay Ramachandran
eaaf106d7c Another try at #372 2021-09-29 12:22:40 -04:00
Ajay Ramachandran
86e26025f4 Safe navigation 2021-09-28 09:56:32 -04:00
Ajay Ramachandran
4470f0b60b Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-09-28 09:50:26 -04:00
Ajay Ramachandran
3873aa61bc Release client even if an error occurs
#372
2021-09-28 09:50:24 -04:00
Ajay Ramachandran
3335d54153 Log stack for unhandled errors 2021-09-28 09:48:24 -04:00
Ajay Ramachandran
ad3f2088ef Merge pull request #370 from mchangrh/switch-axios
replace node-fetch with axios in src
2021-09-27 20:24:34 -04:00
Ajay Ramachandran
39baa4871a Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-09-27 20:17:24 -04:00
Ajay Ramachandran
9d2c5ed74e Call connect manually to catch errors
Fix #372
2021-09-27 20:17:02 -04:00
Michael C
6d76bea5c5 remove node-fetch, types and @types/request 2021-09-26 18:15:24 -04:00
Michael C
82c5c70eb7 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into switch-axios 2021-09-26 18:13:27 -04:00
Ajay Ramachandran
bb448d6d55 Merge pull request #369 from mchangrh/reWriteAxios
rewrite tests with axios
2021-09-26 18:11:17 -04:00
Michael C
44511acd27 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into reWriteAxios 2021-09-26 18:08:30 -04:00
Michael C
5aa48cdbdf Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into switch-axios 2021-09-26 18:04:22 -04:00
Ajay Ramachandran
5f19d3ee09 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-09-26 15:02:39 -04:00
Ajay Ramachandran
598e4e2b79 Always restart db 2021-09-26 15:02:37 -04:00
Ajay Ramachandran
161091513d Merge pull request #365 from mchangrh/updateDependencies
update dependencies, add shims for node-fetch v3
2021-09-26 14:41:56 -04:00
Ajay Ramachandran
9619e95283 Don't use cache when no successful submissions exist 2021-09-26 11:11:08 -04:00
Michael C
6433f50edf replace node-fetch with axios in src 2021-09-23 01:21:10 -04:00
Michael C
28d637f620 remove extra async and extra utils 2021-09-22 23:34:46 -04:00
Michael C
4e50f0ab4b remaining tests 2021-09-22 23:18:31 -04:00
Michael C
a028eaa41a object-curly-spacing 2021-09-22 18:52:35 -04:00
Michael C
5dcc90b31a fix CI errors 2021-09-22 18:46:13 -04:00
Michael C
a5c88693b8 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into reWriteAxios 2021-09-22 18:44:23 -04:00
Michael C
9b6808273b json as any 2021-09-22 17:57:12 -04:00
Michael C
c779c2c19e everything to postClearCache 2021-09-22 17:50:06 -04:00
Ajay Ramachandran
a23387c877 raise redis memory 2021-09-21 23:19:20 -04:00
Ajay Ramachandran
0f0d43cc17 Merge pull request #362 from mchangrh/getLockReason
getLockReason
2021-09-21 19:06:36 -04:00
Michael C
94e1e8c377 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into reWriteTests 2021-09-21 02:03:05 -04:00
Michael C
5758f6512d move utils to seperate files and folder, update imports 2021-09-21 02:02:17 -04:00
Michael C
22c4468180 bump eslint, fix lint warning, made request dev 2021-09-21 00:47:35 -04:00
Michael C
1dd534cce9 update dependencies, add shims for node-fetch v3 2021-09-20 01:43:19 -04:00
Michael C
ce0073e7b0 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into getLockReason 2021-09-18 23:26:49 -04:00
Michael C
c0074c9f8c add tests 2021-09-18 23:24:23 -04:00
Michael C
0fc39cf5f2 fix logic in getLockReason 2021-09-18 02:47:34 -04:00
Michael C
d4d9f2d4d7 remove unnecessary async await 2021-09-17 00:03:42 -04:00
Michael C
802dd50163 naming 2021-09-17 00:01:29 -04:00
Michael C
9e9fcd47c0 finished other tests 2021-09-16 23:59:19 -04:00
Michael C
e7d55d1e1b everything after postClearCache 2021-09-16 23:05:16 -04:00
Michael C
7cef510b29 quoted 2021-09-16 20:50:59 -04:00
Michael C
870ade6fa9 postSkipSegments 2021-09-16 20:44:12 -04:00
Ajay Ramachandran
803c3f2a29 Merge pull request #357 from mchangrh/getUserStats
add getUserStats
2021-09-15 20:45:52 -04:00
Ajay Ramachandran
4d9e595470 Rename user stats parameters 2021-09-15 20:44:20 -04:00
Ajay Ramachandran
bcdbc5fd60 Merge pull request #360 from HaiDang666/getService_helper
Add getService helper function
2021-09-15 20:30:48 -04:00
Michael C
61d7103f82 create getLockReason 2021-09-13 10:57:46 -04:00
Haidang666
93c69248d9 Add getService helper function 2021-09-13 14:49:17 +07:00
Michael C
18c1735087 acceptance 2021-09-07 00:48:01 -04:00
Michael C
76fe3f1165 stage of grief - depression 2021-09-07 00:44:39 -04:00
Michael C
6b7fdb8d9e please accept my double quotes 2021-09-07 00:38:15 -04:00
Michael C
46270cfe84 partialDeepEquals for varying orders 2021-09-07 00:32:32 -04:00
Michael C
2c2e9a2900 all columns in quotes 2021-09-07 00:18:15 -04:00
Michael C
3d30eea1cb add categoryStats and typeStats 2021-09-07 00:13:52 -04:00
Ajay Ramachandran
1e05c04a39 Allow mute and skip segments with same times 2021-09-05 22:40:40 -04:00
Michael C
6e55f9d979 everything up to purgeAllSegments 2021-09-04 19:23:43 -04:00
Michael C
4a394dd6dd Merge branch 'getUserStats' of github.com:mchangrh/SponsorBlockServer into getUserStats 2021-09-04 17:07:38 -04:00
Michael C
9b05ee96af add getUserStats 2021-09-04 17:06:49 -04:00
Michael C
97214bef1b add getUserStats 2021-09-04 17:05:23 -04:00
Ajay Ramachandran
1823a91d54 Limit mute action type to specific categories 2021-09-04 00:33:37 -04:00
Ajay Ramachandran
6f29b807c5 Merge pull request #356 from mchangrh/patch-1
avoid unnecessary eslint-disable-line
2021-09-03 19:20:24 -04:00
Michael M. Chang
b50b215f20 avoid unnecessary eslint-disable-line 2021-09-03 17:48:00 -04:00
Ajay Ramachandran
33318ef4c6 Add youtube api cache 2021-09-02 18:33:52 -04:00
Ajay Ramachandran
2a284d7f25 Treat segments where end time of one equals start time of the other as not overlapping 2021-09-02 13:07:49 -04:00
Ajay Ramachandran
9cbea88f6f Merge pull request #353 from mchangrh/statusOptions
get status with options
2021-09-02 12:04:38 -04:00
Ajay Ramachandran
2a1b645241 Merge pull request #348 from mchangrh/searchSegments
add getSearchSegments endpoint
2021-09-02 00:53:55 -04:00
Michael C
74626f8e3f more endpoints! 2021-09-01 23:49:18 -04:00
Michael C
fa1166e5d8 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into searchSegments 2021-09-01 23:26:55 -04:00
Michael C
664db71104 get status with options 2021-09-01 23:24:43 -04:00
Ajay Ramachandran
cfefb7c629 Merge pull request #352 from mchangrh/getStatus
add getStatus and cases
2021-09-01 17:11:25 -04:00
Michael C
e12724af15 add getStatus and cases 2021-09-01 16:52:41 -04:00
Ajay Ramachandran
d6a986d6cf Disable shadow hidden when vip upvotes 2021-09-01 15:28:39 -04:00
Michael C
e9bffd0cf2 add test cases and fixed bugs 2021-09-01 13:53:06 -04:00
Michael C
9bef529486 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into searchSegments 2021-08-31 23:10:04 -04:00
Ajay Ramachandran
ba7fb6525f Allow VIP to submit poi segments at any time 2021-08-31 12:27:15 -04:00
Ajay Ramachandran
df904e3744 Merge pull request #350 from mchangrh/poi-min-start-time
add config key for poiMinimumStartTime
2021-08-31 12:25:17 -04:00
Ajay Ramachandran
b369916904 Merge pull request #347 from mchangrh/beautify-nginx
Beautify nginx
2021-08-31 12:23:57 -04:00
Ajay Ramachandran
13480fe96c Merge pull request #346 from mchangrh/update-dependencies
Update dependencies & eslint
2021-08-31 12:23:48 -04:00
Ajay Ramachandran
44711267fd Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-31 12:10:25 -04:00
Ajay Ramachandran
9849fba97a Don't crash if failed to get ip from db 2021-08-31 12:10:23 -04:00
Michael C
bb02033567 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into searchSegments 2021-08-31 01:18:18 -04:00
Michael C
aab95a1adc add config key for poiMinimumStartTime 2021-08-29 21:43:21 -04:00
Ajay Ramachandran
9f762ac206 Merge pull request #349 from mchangrh/update-matrix
update matrix link
2021-08-29 21:27:16 -04:00
Michael C
5f8a319f48 update matrix link 2021-08-29 14:58:41 -04:00
Ajay Ramachandran
24e82309c4 Merge pull request #345 from mchangrh/poi-restriction
disallow POI before 1 second
2021-08-28 16:18:52 -04:00
Michael C
5310205911 catch and throw error outside of if 2021-08-28 01:54:50 -04:00
Michael C
9f7abf1865 Revert "fix error with errors"
This reverts commit 7601a1d4bf.
2021-08-28 01:53:53 -04:00
Michael C
e53f65f324 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into update-dependencies 2021-08-28 01:49:23 -04:00
Michael C
7601a1d4bf fix error with errors 2021-08-28 01:48:48 -04:00
Michael C
9e488b8917 Merge branch 'master' of github.com:mchangrh/SponsorBlockServer into poi-restriction 2021-08-28 01:39:52 -04:00
Michael C
b3320ab0fd submit test as poi_highlight 2021-08-28 01:38:00 -04:00
Michael M. Chang
d494c23059 Update src/routes/postSkipSegments.ts
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-08-28 01:36:41 -04:00
Ajay Ramachandran
7ef28d859f Merge pull request #343 from mchangrh/409-ban-exists
re-shadowban user
2021-08-28 00:20:22 -04:00
Ajay Ramachandran
c3a5b22dad Move unHideSubmissions to helper function 2021-08-28 00:18:31 -04:00
Ajay Ramachandran
dea0bce0c4 Merge pull request #342 from mchangrh/no-colon
throw error 400 when start or endtime has colon
2021-08-28 00:14:52 -04:00
Michael C
0d6731fcc6 remove accidental inclusion of api-prop 2021-08-27 21:47:30 -04:00
Michael C
840ccb517e add getSearchSegments endpoint 2021-08-27 21:46:39 -04:00
Michael C
656d81e5dd reverting some ugly tabs 2021-08-27 17:59:40 -04:00
Michael C
50df8e7dd9 prettify nginx.conf
- align to tab
- align to block
- remove blank lines & trailing whitespaces

- 404 on database.db
- 404 on /download
- 404 on /test
2021-08-27 17:50:50 -04:00
Michael C
1c2dd055c1 Update dependencies & eslint
- update API-Docs link
- cast err as string to appease eslint
- update package and bump minimum to fix security issue
- removed unnecessary filters from gitignore
2021-08-27 17:09:31 -04:00
Michael C
c448bb3d9a add test case 2021-08-27 16:44:29 -04:00
Michael C
268008945c disallow POI before 1 second 2021-08-27 16:41:26 -04:00
Ajay Ramachandran
d99ffdabd7 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-25 18:51:24 -04:00
Ajay Ramachandran
4f981c1229 Clarify lock reason 2021-08-25 18:51:22 -04:00
Michael C
265a01dcde re-shadowban user
if user is already shadowbanned but unhideOldSubmissions is true, sets all submissions to hidden. If not true, then return 409 duplicate
2021-08-25 01:56:34 -04:00
Michael C
c3f7b29d44 throw error 400 when start or endtime has colon 2021-08-24 19:12:58 -04:00
Ajay Ramachandran
954ac1eb07 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-24 21:11:42 +02:00
Ajay Ramachandran
b5c6b55380 Update nginx config 2021-08-24 21:10:57 +02:00
Ajay Ramachandran
28982dc84b Fix highlight category in top users 2021-08-22 00:44:24 -04:00
Ajay Ramachandran
5d77b7b03e Fix typo in top users query 2021-08-20 15:18:20 -04:00
Ajay Ramachandran
fa866b0677 Add highlight category to top users 2021-08-20 15:00:22 -04:00
Ajay Ramachandran
f1f5bdb2be Fix test 2021-08-17 22:08:51 -04:00
Ajay Ramachandran
765e01cb00 Add working to gitignore 2021-08-17 22:01:23 -04:00
Ajay Ramachandran
5965879ed1 Rename highlight category to poi_highlight 2021-08-17 22:01:12 -04:00
Ajay Ramachandran
987d91f293 Hide submissions that are at -1 votes 2021-08-17 16:46:45 -04:00
Ajay Ramachandran
c869e60b04 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-10 23:13:59 -04:00
Ajay Ramachandran
d653f00a2d Print when partial deep equals fails 2021-08-10 23:13:56 -04:00
Ajay Ramachandran
1cbd162a22 Support commas in timestamps 2021-08-10 23:12:20 -04:00
Ajay Ramachandran
0ec87b967d Merge pull request #339 from ajayyy/fix-ci
Fix ci
2021-08-10 10:59:45 -04:00
Ajay Ramachandran
0fded0022c Fix userCount using lower case 2021-08-10 10:58:20 -04:00
Ajay Ramachandran
fa901add35 print error in tests 2021-08-10 10:52:02 -04:00
Ajay Ramachandran
f24c962785 Catch postgres exceptions
Fix #338
2021-08-10 09:50:32 -04:00
Ajay Ramachandran
f3e5b360c4 Check against number for username lock 2021-08-10 00:37:43 -04:00
Ajay Ramachandran
e417dade68 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-09 10:03:43 -04:00
Ajay Ramachandran
54f8f67ed5 Don't allow username change for banned users 2021-08-09 10:03:40 -04:00
Ajay Ramachandran
23b9375570 Merge pull request #337 from mchangrh/getUserInfo-update
getUserInfo update
2021-08-06 01:20:39 -04:00
Michael C
58551ba37f add maxRewardTime 2021-08-06 00:51:22 -04:00
Michael C
5ad7c6a3ba catch all error in endpoint 2021-08-06 00:51:22 -04:00
Ajay Ramachandran
71c01c0f3b add option to get ban status from user info 2021-08-05 20:11:05 -04:00
Ajay Ramachandran
326f9e6e93 Fix sqlite 2021-08-05 20:03:37 -04:00
Ajay Ramachandran
9f0f9054d1 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-05 16:50:41 -04:00
Ajay Ramachandran
00858b6633 Remove duplicate usernames and make unique
Closes #336
2021-08-05 16:50:39 -04:00
Ajay Ramachandran
0463513d5d Merge pull request #335 from mchangrh/mchangrh/deepPartialEquals
use deepPartialEquals instead of multiple assert.strictEquals
2021-08-03 21:06:55 -04:00
Ajay Ramachandran
56a36f34a9 Merge pull request #334 from HaiDang666/update-query
Add Limit 1 when check user as vip
2021-08-03 21:06:51 -04:00
Ajay Ramachandran
73dfe2ef11 Remove casting 2021-08-03 21:05:07 -04:00
Ajay Ramachandran
94b82b6865 Fix warnings 2021-08-03 21:02:45 -04:00
Ajay Ramachandran
1678dcac82 Get all warnings 2021-08-03 13:24:23 -04:00
Ajay Ramachandran
497a509d60 Send longest warning reason 2021-08-03 13:18:38 -04:00
Ajay Ramachandran
bddadc6a9e Change default max reward time 2021-08-03 12:48:48 -04:00
Michael C
ed0d832e08 use partialDeepEquals for tests 2021-08-03 00:19:37 -04:00
Haidang666
38a09b164d Add Limit 1 when check user as vip 2021-08-03 09:28:28 +07:00
Michael C
b39c06a9ef add tests, new partialDeepEquals 2021-08-02 21:59:06 -04:00
Ajay Ramachandran
09626ee6f6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-08-02 16:25:07 -04:00
Ajay Ramachandran
3a8076fc3c Indent switch case 2021-08-02 16:25:04 -04:00
Ajay Ramachandran
31a7838851 Merge pull request #331 from mchangrh/segmentInfo-userAgent
include userAgent in segmentInfo
2021-08-01 16:00:38 -04:00
Michael C
7dff254604 add userAgent to tests 2021-08-01 15:28:17 -04:00
Michael C
d4078f0f91 return all from segmentInfo 2021-08-01 15:28:17 -04:00
Ajay Ramachandran
90152240c7 Merge pull request #328 from HaiDang666/refactor
Use assert in test
2021-08-01 12:41:15 -04:00
Haidang666
85e78d2490 Use assert in test 2021-08-01 14:59:25 +07:00
Ajay Ramachandran
3368615a77 Add test for body user agent 2021-08-01 02:57:02 -04:00
Ajay Ramachandran
ee8d20a43d Fix full user agent being saved 2021-08-01 02:46:21 -04:00
Ajay Ramachandran
8f0f01e6b2 Parse user agent header 2021-07-31 21:49:10 -04:00
Ajay Ramachandran
bdf0953f35 Save entire user agent 2021-07-31 21:03:47 -04:00
Ajay Ramachandran
e056c30f05 Merge pull request #327 from HaiDang666/324_user-agent
Store user-agent in postSkipSegment
2021-07-31 20:56:00 -04:00
Ajay Ramachandran
b07979cbc7 Merge pull request #326 from mchangrh/reenable-warning
re-enable warning if still within issue time
2021-07-31 20:55:00 -04:00
Haidang666
01cbf67bcb Fix test on new warning reason format 2021-07-30 13:50:46 +07:00
Haidang666
ce193b60f7 Store user-agent in postSkipSegment 2021-07-30 13:47:21 +07:00
Ajay Ramachandran
2057b0cfa6 Change default warning mininum 2021-07-29 23:53:13 -04:00
Ajay Ramachandran
366de4955b Send warning reason with votes and use quotes 2021-07-29 23:53:02 -04:00
Michael C
32056ab2f1 re-enable warning if still within issue time 2021-07-28 02:52:00 -04:00
Ajay Ramachandran
d4e45cc3b0 Fix newlines in lock categories error message 2021-07-27 13:03:31 -04:00
Ajay Ramachandran
48aa6d6e05 Fixed odd formatting on lock categories error 2021-07-27 12:59:35 -04:00
Ajay Ramachandran
5ca3cb18e4 Merge pull request #323 from HaiDang666/318_display-lock-reason
Return reason in locked categories when submission fail
2021-07-27 12:56:20 -04:00
Haidang666
c701998a35 return reason in locked categories when submission fail 2021-07-27 14:03:51 +07:00
Ajay Ramachandran
4453705938 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-27 00:36:09 -04:00
Ajay Ramachandran
144f3fa035 Don't strictly check for locked videos 2021-07-27 00:36:07 -04:00
Ajay Ramachandran
fd507d6657 Merge pull request #320 from HaiDang666/refactor-postSkipSegments
Split code in postSkipSegment
2021-07-26 23:49:08 -04:00
Ajay Ramachandran
9aa0ff6de6 Merge pull request #319 from HaiDang666/266_final
Update: most upvoted segments on locked videos as locked submissions
2021-07-26 23:48:58 -04:00
Ajay Ramachandran
37ea8adb73 assert fixed value 2021-07-26 23:46:26 -04:00
Felix
0d6992b80b Merge branch 'master' into refactor-postSkipSegments 2021-07-27 10:40:38 +07:00
Ajay Ramachandran
7b15957bb8 fix tests 2021-07-25 14:34:55 -04:00
Ajay Ramachandran
b1c5c38bdb Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-24 16:04:42 -04:00
Ajay Ramachandran
e6b2243496 Add link to discord and matrix 2021-07-24 16:04:40 -04:00
Haidang666
0eb298a943 Update query and test 2021-07-24 15:09:30 +07:00
Haidang666
22debb4374 Split code in postSkipSegment 2021-07-23 13:54:44 +07:00
Ajay Ramachandran
ef71405143 Merge pull request #321 from mchangrh/fixci
fix tests and linting
2021-07-23 00:13:02 -04:00
Ajay Ramachandran
0990a9b87d Add semicolon 2021-07-22 20:00:42 -04:00
Michael C
87727ef360 fix tests and linting 2021-07-22 17:50:39 -04:00
Ajay Ramachandran
dbc8558ec8 Log submissions for warned users 2021-07-22 11:12:22 -04:00
Ajay Ramachandran
143cdf529d Include default message on error from warning.
Also show userID
2021-07-22 11:02:38 -04:00
Ajay Ramachandran
919c47c993 Fix quote error 2021-07-22 00:08:30 -04:00
Haidang666
2773c5f500 Update: most upvoted segments on locked videos as locked submissions 2021-07-21 16:16:58 +07:00
Ajay Ramachandran
c070e5f40d Fix falsey values getting through tests 2021-07-20 17:21:22 -04:00
Ajay Ramachandran
31103faf92 Improve shadow ban check 2021-07-20 17:15:15 -04:00
Ajay Ramachandran
05ec937b06 Fix youtube api cache key 2021-07-20 13:54:30 -04:00
Ajay Ramachandran
3c5a27d9f5 fix incorrect sql 2021-07-20 13:42:31 -04:00
Ajay Ramachandran
1ad805fda3 reset video duration when vip upvotes hidden segment 2021-07-20 13:40:22 -04:00
Ajay Ramachandran
6171ba7c7a Print times of submissions on locked categories 2021-07-20 12:41:27 -04:00
Ajay Ramachandran
c60b82d40a Only treat video as changed duration if both submitted and api agree 2021-07-20 12:38:45 -04:00
Ajay Ramachandran
13a04a0442 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-19 16:14:17 -04:00
Ajay Ramachandran
db3701d76a Don't fail for invalid userID 2021-07-19 16:13:14 -04:00
Ajay Ramachandran
a02d14e425 Merge pull request #317 from mchangrh/stricter-eslint
Stricter ESLint rules & linting fixes
2021-07-18 14:39:17 -04:00
Michael C
f774df972d Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into stricter-eslint 2021-07-18 14:30:27 -04:00
Ajay Ramachandran
04ed1112a4 Merge pull request #314 from mchangrh/getUserInfo/param
add warningReason and specify returned types
2021-07-18 11:52:13 -04:00
Michael C
2075ed46e1 added null warningReason 2021-07-18 02:39:37 -04:00
Michael C
fdb88dd401 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into getUserInfo/param 2021-07-18 02:38:12 -04:00
Michael C
205958464a new stringDeepEquals 2021-07-18 02:33:57 -04:00
Michael C
a7aaffcfe5 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into stricter-eslint 2021-07-18 02:27:48 -04:00
Ajay Ramachandran
0222b1fccd Update package lock 2021-07-16 16:23:08 -04:00
Ajay Ramachandran
b98d6fd8ca Ignore votes from short ids 2021-07-16 16:22:55 -04:00
Ajay Ramachandran
3f6baebd71 Add friendlier message for short userID 2021-07-16 16:19:00 -04:00
Ajay Ramachandran
ce2aa67832 Disable info logging on production 2021-07-15 16:06:04 -04:00
Ajay Ramachandran
83a77dfc74 Use strict equals 2021-07-15 14:03:30 -04:00
Ajay Ramachandran
27f406f757 Fix username existence check 2021-07-15 14:02:08 -04:00
Ajay Ramachandran
72e17b06fc Don't break if cron schedule is missing 2021-07-15 13:55:02 -04:00
Ajay Ramachandran
49e1e38f05 Enable info logs in production 2021-07-15 13:15:52 -04:00
Ajay Ramachandran
d64a61738f Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-15 12:32:02 -04:00
Ajay Ramachandran
d7b8c32c10 Remove lock when undoing vote 2021-07-15 12:32:00 -04:00
Michael C
42423a86a6 forgot to return reason 2021-07-14 14:30:36 -04:00
Michael C
8ee51a1cb0 testing CI 2021-07-14 14:11:34 -04:00
Michael C
5f2bc37e96 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into stricter-eslint 2021-07-13 15:55:03 -04:00
Michael C
1ba1450e9c string literal fixes & npm run postgres:docker 2021-07-13 15:45:24 -04:00
Ajay Ramachandran
afabf3650b Merge pull request #307 from mchangrh/getLockCategories/reason
add reason to getLockCategories
2021-07-13 14:48:22 -04:00
Michael C
59bad90480 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into getLockCategories/reason 2021-07-13 13:51:51 -04:00
Ajay Ramachandran
a342ad5bda Merge pull request #316 from mchangrh/400-on-noparam
Return 400 if no parameters specified
2021-07-12 14:17:20 -04:00
Ajay Ramachandran
3d0b9edb9c Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-12 11:05:14 -04:00
Ajay Ramachandran
a23ec160c0 Make reputation take into account more recent segments 2021-07-12 11:05:12 -04:00
Michael C
b5a29675d6 fix more non-format string-concat 2021-07-12 02:48:49 -04:00
Michael C
8b3ffe5d0d fix eslint for tests 2021-07-12 02:43:46 -04:00
Michael C
c0b1d201ad fix non-format eslint in src/ 2021-07-12 02:12:22 -04:00
Michael C
a8f7080bf2 fix typo in tests 2021-07-12 00:32:51 -04:00
Ajay Ramachandran
9445a06871 Merge pull request #312 from HaiDang666/221_archive-down-votes
archive down votes
2021-07-11 23:21:14 -04:00
Michael C
d9a66a5894 quote & check for db version 2021-07-12 08:59:12 +07:00
Haidang666
bbb1db014c Add archive downvote function unit test 2021-07-12 08:59:12 +07:00
Haidang666
6b5156468c Add archive downvote segment cron 2021-07-12 08:59:12 +07:00
Michael M. Chang
0b7ba793b4 Merge branch 'master' into 400-on-noparam 2021-07-11 14:27:32 -04:00
Ajay Ramachandran
ef86fceedd Merge pull request #311 from mchangrh/dependency-bump
Update dependencies
2021-07-11 11:52:35 -04:00
Ajay Ramachandran
db6a205f43 Merge pull request #310 from mchangrh/testAssert
Test with assert
2021-07-11 11:51:45 -04:00
Michael C
e8d0da3ce3 add 400 conditions 2021-07-10 16:30:30 -04:00
Michael C
7e977ad811 add warningReason and specify returned types 2021-07-09 12:07:36 -04:00
Michael C
81cae514a0 Update dependencies 2021-07-09 00:31:42 -04:00
Michael C
2d38ef921e use deepStringEqual instead of deepAssert 2021-07-08 00:59:15 -04:00
Michael C
9f05595cd6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into testAssert 2021-07-08 00:51:56 -04:00
Michael C
178ed1e5af replace if tests with assert 2021-07-08 00:39:57 -04:00
Ajay Ramachandran
2105cdf10b Fix segment id test 2021-07-07 18:24:16 -04:00
Ajay Ramachandran
a471e057f5 Remove category from segment id 2021-07-07 18:21:25 -04:00
Ajay Ramachandran
ed5de984f2 Add action type when finding UUID in webhook 2021-07-07 18:16:06 -04:00
Ajay Ramachandran
301f5e7113 Include action type in UUID 2021-07-07 18:12:52 -04:00
Michael C
596dbf4ac8 404 tests 2021-07-07 17:39:16 -04:00
Michael C
9088d9fb9e additional tests 2021-07-07 17:37:40 -04:00
Michael C
5e58efb07f early 400 on skipSegments 2021-07-07 17:36:52 -04:00
Michael C
4a835d5306 fix typos 2021-07-07 16:44:05 -04:00
Michael C
7d62fcd8cc Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into getLockCategories/reason 2021-07-07 16:31:37 -04:00
Ajay Ramachandran
42e7c23ee2 Merge pull request #304 from HaiDang666/234_lockCategories-reason
Lock categories reason
2021-07-07 13:05:31 -04:00
Michael C
50e7f4af8e use .reduce from @HaiDang666 2021-07-07 00:51:08 -04:00
Michael C
3371c6a099 add reason to getLockCategories 2021-07-07 00:22:05 -04:00
Haidang666
feba2af9ed Fix any type 2021-07-06 13:42:08 +07:00
Haidang666
6fcfeb2889 Fix deep equal fail 2021-07-06 13:36:56 +07:00
Haidang666
14f55c9ee5 Add lock category reason 2021-07-06 13:31:44 +07:00
Ajay Ramachandran
e94d1d4bae Merge pull request #306 from mchangrh/remove-disable-eslint
no need for eslint-disable
2021-07-06 01:15:27 -04:00
Michael C
d48b6ea80e no need for eslint-disable 2021-07-06 01:06:29 -04:00
Ajay Ramachandran
8ff8f9628a Merge pull request #301 from mchangrh/eslint-gh-actions
Add ESLint workflow
2021-07-06 01:01:36 -04:00
Ajay Ramachandran
4272f9de99 Merge pull request #305 from ajayyy/userid-limit
Minimum userID size
2021-07-06 01:00:44 -04:00
Ajay Ramachandran
8e0e66d662 Merge pull request #298 from ajayyy/mute-skip
Silent skip type
2021-07-06 01:00:22 -04:00
Ajay Ramachandran
48349070b3 Combine action type segments when sorting overlapping 2021-07-06 00:57:57 -04:00
Ajay Ramachandran
2379899f02 Add a minimum size to userID when submitting 2021-07-06 00:49:07 -04:00
Ajay Ramachandran
35e1cf5733 Add test for submitting 2021-07-06 00:22:01 -04:00
Ajay Ramachandran
139dff97ef Add tests for normal get segments 2021-07-06 00:19:16 -04:00
Ajay Ramachandran
be006403ed Add tests for getting segment by hash 2021-07-06 00:11:04 -04:00
Ajay Ramachandran
f67a805c1f Add issue assigning action 2021-07-05 20:50:22 -04:00
Ajay Ramachandran
35cfb01973 Merge pull request #303 from mchangrh/lockCategories/hashVideoID
add hashedVideoID to lockCategories
2021-07-05 20:33:22 -04:00
Michael C
fcea42bf38 fix typos, add upgrade_18 2021-07-05 20:05:54 -04:00
Michael C
ad3fe44418 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into eslint-gh-actions 2021-07-05 20:02:58 -04:00
Michael C
ede02eaa8c add hashedVideoID to lockCategories 2021-07-05 20:01:10 -04:00
Ajay Ramachandran
ab27cbef07 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into mute-skip 2021-07-05 13:29:26 -04:00
Ajay Ramachandran
c2d4f2578c Merge pull request #300 from mchangrh/appease-eslint
Appease eslint
2021-07-05 13:29:18 -04:00
Ajay Ramachandran
fa4c77b495 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into mute-skip 2021-07-05 13:27:25 -04:00
Ajay Ramachandran
e78c9703b8 Merge pull request #299 from mchangrh/getLockCategories
Get lock categories
2021-07-05 13:27:14 -04:00
Ajay Ramachandran
28e7ec0ef9 Change db upgrade to v19 2021-07-05 13:26:49 -04:00
Ajay Ramachandran
c3dcd58390 Rename type 2021-07-05 13:25:54 -04:00
Ajay Ramachandran
c77814235c Add action type to getSkipSegments 2021-07-05 13:23:31 -04:00
Michael C
e8d5dbec3e add eslint workflow 2021-07-05 03:18:58 -04:00
Michael C
d5204e9813 lint & fix tests 2021-07-05 03:14:05 -04:00
Michael C
d29c9613b9 type config & remove await from memoryCache 2021-07-05 02:59:01 -04:00
Michael C
351c89f235 add types from ajayyyy/lru-diskcache
- added existing types
- disbled no-unused-vars since there is no other way
2021-07-05 02:40:17 -04:00
Michael C
9a4cd431e8 rewrite getLockCategores to new spec 2021-07-05 02:33:32 -04:00
Michael C
cef6d5f365 fix eslint errors 2021-07-04 23:36:47 -04:00
Michael C
1c116eda3b Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into getLockCategories 2021-07-04 23:33:21 -04:00
Michael C
a860e96d35 getLockCategoresByHash 2021-07-04 23:33:12 -04:00
Ajay Ramachandran
d20320e87e Add post for actionType
untested
2021-07-04 18:35:15 -04:00
Ajay Ramachandran
43ae471038 Merge pull request #294 from mchangrh/fix-eslint
fix eslint-errors
2021-07-04 18:21:00 -04:00
Ajay Ramachandran
00ff3ecd38 Merge branch 'master' into fix-eslint 2021-07-04 18:19:52 -04:00
Ajay Ramachandran
b6d6cb4359 Merge pull request #293 from mchangrh/add-eslint
Add eslint
2021-07-04 18:18:50 -04:00
Ajay Ramachandran
5a09134d3f Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into pr/mchangrh/293 2021-07-04 18:17:18 -04:00
Michael C
719a0956ac add getLockCategories 2021-07-04 17:03:28 -04:00
Michael C
3c197ec3d9 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into fix-eslint 2021-07-04 15:23:00 -04:00
Ajay Ramachandran
0b27244c06 Fix audit issue 2021-07-04 14:21:28 -04:00
Ajay Ramachandran
0a60ca6468 Add repeating category for fetching by hash
Fixes #235
2021-07-04 14:20:54 -04:00
Ajay Ramachandran
990572ff31 Add parameter to fetch specific segments 2021-07-04 14:15:17 -04:00
Michael C
8df0c31d35 consistent return and sendStatus 2021-07-04 02:04:39 -04:00
Michael C
d89b26b77d fix eslint-errors 2021-07-04 01:36:03 -04:00
Michael C
401be9d9fa match sponsorblock warn rules 2021-07-03 22:51:26 -04:00
Michael C
28341fc1f3 Add eslint based off of SponsorBlock 2021-07-03 22:49:04 -04:00
Ajay Ramachandran
be277d0218 Merge pull request #284 from HaiDang666/283_show-lastest-warning
Show lastest warning when post segment
2021-07-03 22:46:26 -04:00
Ajay Ramachandran
a7315eaee0 Add case for default warning message 2021-07-03 22:45:13 -04:00
Ajay Ramachandran
a1bcd08658 Merge pull request #287 from mchangrh/unhide-vote
VIP upvote should unhide segment
2021-07-03 22:38:41 -04:00
Ajay Ramachandran
cf592554f1 Merge branch 'master' into unhide-vote 2021-07-03 22:37:23 -04:00
Ajay Ramachandran
cb950ac5d7 Merge pull request #288 from mchangrh/remove-altvote
remote vote types 10/11
2021-07-03 22:36:42 -04:00
Ajay Ramachandran
4f29e2c197 Merge pull request #289 from DetachHead/express-promise-router
express-promise-router
2021-07-03 22:36:30 -04:00
Ajay Ramachandran
c9e0acd055 Fix any issue 2021-07-03 17:50:20 -04:00
Ajay Ramachandran
63254159ca Merge pull request #292 from DetachHead/tsc_test
run `tsc` in the `test` script
2021-07-03 17:47:48 -04:00
Ajay Ramachandran
c5fd4b41b6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-07-03 17:27:00 -04:00
Ajay Ramachandran
f5cfd6bfb5 Add try catch in dump database 2021-07-03 17:26:59 -04:00
DetachHead
81c2e7b059 read test script value from package.json 2021-07-03 16:01:29 +10:00
DetachHead
eb481215e3 compile as part of the test script since ts-node doesn't typecheck everything 2021-07-03 15:46:51 +10:00
DetachHead
20335e3f27 use express-promise-router to prevent requests timing out on unhandled promise rejections 2021-07-03 14:59:57 +10:00
Michael C
931b3fdc68 disallow vote types 10/11 2021-07-02 23:07:17 -04:00
Michael C
36a5b4e1d3 VIP upvotes unhide segments
also added test for undo-vote
2021-07-02 22:54:54 -04:00
Michael C
107b21c463 restore hidden segments with vip upvote 2021-07-02 21:57:00 -04:00
Haidang666
24480fd18c Revear auto clear unused code 2021-07-01 11:38:29 +07:00
Haidang666
09e50d432e Update postSegment test with reason 2021-07-01 11:31:35 +07:00
Haidang666
402ea35971 Add postSkipSegments return lastes warning reason 2021-07-01 10:33:47 +07:00
Haidang666
7f074554c4 Fix schema md header link 2021-07-01 10:30:45 +07:00
Ajay Ramachandran
f1d22c6ca4 Merge pull request #281 from mchangrh/docker/node-14
multi-stage dockerfile with node:14-alpine
2021-06-30 13:46:12 -04:00
Ajay Ramachandran
7a877a9653 Merge pull request #282 from HaiDang666/276_warn-reason
User warning reason
2021-06-30 13:43:08 -04:00
Ajay Ramachandran
ce59d3f95f Don't fail if row is undefined 2021-06-30 00:01:40 -04:00
Haidang666
081f2d14b7 Add test, Fix sql syntax 2021-06-30 08:59:20 +07:00
Michael C
14a97b4879 multi-stage dockerfile with node:14-alpine 2021-06-29 19:22:18 -04:00
Ajay Ramachandran
4d8526c24d Update dockerfile to node 14 2021-06-29 17:12:04 -04:00
Ajay Ramachandran
66cd88d4c2 Update node in dockerfile 2021-06-29 16:56:26 -04:00
Ajay Ramachandran
1f4da1ab48 Merge pull request #279 from mchangrh/ci-bump
Bump checkout/ setup-node actions
2021-06-29 16:49:32 -04:00
Michael C
30a12a600a bump setup-node and checkout versions 2021-06-29 16:27:35 -04:00
Ajay Ramachandran
994b68bc4c Merge pull request #278 from mchangrh/ci-timeout
add 5 minute timeout to CI, added note in config
2021-06-29 16:26:21 -04:00
Michael C
d710b88c3e add 5 minute timeout to CI, added note in config
- added note in config to use enable_offline_queue to avoid timeouts
- removed wait action from CI
2021-06-29 16:23:52 -04:00
Haidang666
214ddc9807 Add warning reason in postWarning 2021-06-29 14:56:57 +07:00
Ajay Ramachandran
6f18a49ba0 Switch username update to one query 2021-06-28 22:05:15 -04:00
Ajay Ramachandran
8b54e965a2 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-06-28 13:24:04 -04:00
Ajay Ramachandran
0ddde452e3 Auto-lock username when admin changes it
https://github.com/ajayyy/SponsorBlockServer/issues/168
2021-06-28 13:20:57 -04:00
Ajay Ramachandran
7dbd4a3150 Merge pull request #275 from HaiDang666/193_log-username-change
Add log when update username
2021-06-27 18:13:21 -04:00
Ajay Ramachandran
98b5fa7bce Merge pull request #274 from mchangrh/getUserID
GET api/userID
2021-06-27 18:10:35 -04:00
Michael C
33a45ce0a2 fix TS declarations 2021-06-27 01:05:06 -04:00
Haidang666
41ba37c04e Fix boolean comparison, Add log table to schema visual 2021-06-27 11:57:39 +07:00
Haidang666
f3542b7402 Fix column name for postgre 2021-06-27 11:51:04 +07:00
Haidang666
f5bb221ecd Add log when update username 2021-06-27 11:45:42 +07:00
Ajay Ramachandran
07ab48da1f Add disk caching for youtube api calls
Fixes https://github.com/ajayyy/SponsorBlockServer/issues/239
2021-06-26 23:21:51 -04:00
Michael C
2f50d80a75 add explit param 2021-06-26 23:02:52 -04:00
Michael C
b06a6fbb51 redos prevention 2021-06-25 15:57:41 -04:00
Michael C
f2490beea2 put in limits and escapes 2021-06-25 14:35:51 -04:00
Michael C
09ab1dabdf set limit of 64 characters for lookup 2021-06-25 11:57:27 -04:00
Ajay Ramachandran
e1cf360825 Merge pull request #273 from mchangrh/more-tests
more edge cast test cases
2021-06-25 10:48:27 -04:00
Ajay Ramachandran
de8dd1bb8d Merge pull request #272 from HaiDang666/271_database-schema
Database table visualization
2021-06-25 10:47:35 -04:00
Michael C
f29bafe89a fiix tests 2021-06-25 03:37:27 -04:00
Michael C
d4695f0192 add getUserID and tests 2021-06-25 03:33:41 -04:00
Michael C
2ab782f4b6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into more-tests 2021-06-25 00:54:38 -04:00
Haidang666
aa29ad2014 Add database table schema, Fix indent 2021-06-25 10:44:08 +07:00
Ajay Ramachandran
e7fed0f3cf Merge pull request #270 from HaiDang666/240_purge-all-segments
Add purge all segments of a video for VIP user
2021-06-24 02:17:52 -04:00
Ajay Ramachandran
3c3c963fd3 Fixed captialization error 2021-06-24 02:16:26 -04:00
Michael C
ae8a25e481 more edge cast test cases
- check for null instead of 0 #267
- check that parameter specifying multiple overrides repeating parameters
2021-06-24 01:37:51 -04:00
Ajay Ramachandran
8312cfc0aa Move purgeAllSegments up in app.ts 2021-06-24 01:37:50 -04:00
Ajay Ramachandran
0bbb2aa60d Add one more check in tests 2021-06-24 01:36:54 -04:00
Haidang666
9b43ce0ab7 Add purge all segments of VideoId 2021-06-24 12:29:02 +07:00
Ajay Ramachandran
f71cd57bc7 Fix top users 2021-06-24 01:25:26 -04:00
Ajay Ramachandran
1570657e28 Merge pull request #268 from mchangrh/pg-ci
PostgreSQL docker CI
2021-06-24 00:10:37 -04:00
Ajay Ramachandran
0fbfee8dc8 Use logger instead of console.log 2021-06-24 00:08:19 -04:00
Ajay Ramachandran
7269dc4e5f Remove old index 2021-06-24 00:02:00 -04:00
Ajay Ramachandran
c5245cb8e2 Save more info in unlisted video endpoint 2021-06-23 23:58:33 -04:00
Ajay Ramachandran
15b3cb20b3 Remove print statement 2021-06-23 20:11:11 -04:00
Ajay Ramachandran
42da1b6c23 Add endpoint to submit unlisted videos
A temporary measure which will be removed next month

https://support.google.com/youtube/answer/9230970
2021-06-23 19:19:30 -04:00
Michael C
b62db5675d update CI names and path
move docker-compose to new folder
rename action names
2021-06-23 15:48:02 -04:00
Michael C
da92f2082d set up postgres CI route
uses env flag TEST_POSTGRES since the sqlite test also runs with env flag CI true
2021-06-23 15:35:08 -04:00
Ajay Ramachandran
746dc4f81d Merge pull request #232 from MRuy/fix/prepare-statements
Fix/prepare statements
2021-06-21 19:06:29 -04:00
Nanobyte
7b9e06a471 Merge branch 'master' into fix/prepare-statements 2021-06-22 01:05:48 +02:00
Nanobyte
7c3c1988a3 Fix getTopUsers 2021-06-22 01:00:22 +02:00
Nanobyte
a005a961f9 Fix test cases 2021-06-22 00:59:56 +02:00
Nanobyte
fb87e180da Fix postgres type cast
Postgres is handling numbers as 64bit and requires special handling to prevent returning numbers as string
2021-06-22 00:59:22 +02:00
Nanobyte
4b1f5b4a44 Remove console log from test case 2021-06-22 00:56:00 +02:00
Ajay Ramachandran
0b24871415 Fix comment in reputation test 2021-06-21 18:42:54 -04:00
Ajay Ramachandran
a7cb0959e2 Merge pull request #262 from mchangrh/repeated-param
parse repeated parameters
2021-06-21 14:21:17 -04:00
Nanobyte
11e6c93932 Merge remote-tracking branch 'upstream/master' into fix/prepare-statements 2021-06-21 18:19:50 +02:00
Michael C
dd74dd3b1b parse repeated parameters 2021-06-21 00:33:48 -04:00
Ajay Ramachandran
9351bef61c Add preview category to leaderboard 2021-06-20 15:56:02 -04:00
Ajay Ramachandran
f6d79616a4 Fix leaderboard not working with postgres 2021-06-20 13:59:53 -04:00
Ajay Ramachandran
48d88614fb Move shadow ban list to public db
Warning: Migration is not automatic
2021-06-20 13:41:35 -04:00
Ajay Ramachandran
f45241d494 Merge pull request #259 from mchangrh/shadowban-clear-cache
clearCache after shadowban
2021-06-20 13:05:49 -04:00
Ajay Ramachandran
8d405c1013 Merge pull request #261 from DetachHead/master
remove async modifier which is no longer allowed in interfaces
2021-06-20 13:05:17 -04:00
Ajay Ramachandran
df1d742339 Use for each instead of map 2021-06-20 13:04:52 -04:00
Ajay Ramachandran
96015d402b Make reputation take into account self downvotes 2021-06-20 12:57:32 -04:00
DetachHead
85a30369c4 remove async modifier which is no longer allowed in interfaces 2021-06-19 17:59:18 +10:00
Michael C
47289db13e clearCache after shadowban 2021-06-18 20:57:01 -04:00
Ajay Ramachandran
1770608525 Merge pull request #257 from mchangrh/vip-cache-clear
VIP endpoint for clearing cache of video
2021-06-18 19:01:08 -04:00
Ajay Ramachandran
183462ff85 Add brackets 2021-06-18 18:49:37 -04:00
Michael C
b84241c6ad use isUserVIP instead 2021-06-18 18:44:43 -04:00
Michael C
c13bc6cfbd added tests and route 2021-06-18 17:46:18 -04:00
Michael C
04da532962 implement #253 2021-06-18 16:38:24 -04:00
Ajay Ramachandran
fb68bd46c8 Merge pull request #256 from mchangrh/segmentInfo-error
made 400/404 behaviour consistent with API docs
2021-06-18 16:31:55 -04:00
Michael C
4963f4dc08 style fixes 2021-06-18 15:33:14 -04:00
Michael C
c92e44bb1d made 400/404 behaviour consistent with API docs 2021-06-18 14:43:59 -04:00
Ajay Ramachandran
1dcb63f2cc Fix typo in test 2021-06-17 19:09:24 -04:00
Ajay Ramachandran
b9bcc35dd2 Allow removing warnings created by anyone 2021-06-17 19:08:36 -04:00
Ajay Ramachandran
0b967b9f45 Merge pull request #252 from mchangrh/segmentInfo
Implementation of segmentInfo and new userInfo properties
2021-06-16 13:24:39 -04:00
Ajay Ramachandran
20ae560bb1 Add semicolons 2021-06-16 13:23:25 -04:00
Michael C
7fe787c5ab remove extra properties 2021-06-16 00:53:34 -04:00
Ajay Ramachandran
5fe6ce6656 Merge pull request #250 from mchangrh/fix-getskipsegment-test
Fix Test Suite
2021-06-16 00:47:55 -04:00
Ajay Ramachandran
47ddaaad7b Merge pull request #251 from mchangrh/getSkipSegment-400
skipSegments return 400 if bad categories
2021-06-16 00:46:54 -04:00
Michael C
8dcc1a4a53 add getSegmentInfo with tests 2021-06-16 00:33:51 -04:00
Michael C
0a8f7aa39d skipSegments return 400 if bad categories 2021-06-15 23:01:26 -04:00
Michael C
31071ddb17 new test cases 2021-06-15 21:56:20 -04:00
Michael C
a003733e51 fix test suite 2021-06-15 21:29:36 -04:00
Michael C
13b105504b remove timeSubmitted from query 2021-06-15 17:16:32 -04:00
Michael C
3b16cdb920 add last lastSegmentID 2021-06-15 17:08:17 -04:00
Michael C
607b7cbb0a add ignored counts 2021-06-15 15:50:41 -04:00
Ajay Ramachandran
87c6dab41d Merge pull request #248 from MRuy/feature/add-version-to-databasejson
Add version to database.json
2021-06-15 11:58:24 -04:00
Nanobyte
859ad6ea38 Add version to database.json 2021-06-15 17:50:18 +02:00
Ajay Ramachandran
3e73148390 Merge pull request #245 from mchangrh/reconfigure-cors
remove CORS from nginx, add to express
2021-06-15 01:04:26 -04:00
Ajay Ramachandran
eb2b41bc8a Merge pull request #243 from MRuy/feature/lock-username
Add lock username
2021-06-15 01:04:20 -04:00
Ajay Ramachandran
75981a3e5f Fix copy mistake 2021-06-15 01:03:37 -04:00
Michael C
062faba8d1 remove CORS from nginx, add to express 2021-06-14 20:29:02 -04:00
Ajay Ramachandran
52f61c08a5 Merge pull request #241 from MRuy/fix/webhook-default-value
Fix webhook default value
2021-06-14 19:51:10 -04:00
Nanobyte
34fd78961b Add username lock 2021-06-15 00:09:37 +02:00
Nanobyte
9cf68b8903 Fix test config adminUserID 2021-06-15 00:08:55 +02:00
Ajay Ramachandran
d0526566c4 Merge pull request #242 from mchangrh/add-delete-cors
add delete to CORS for /api/lockCategories
2021-06-14 16:26:23 -04:00
Ajay Ramachandran
0271556c07 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-06-14 22:25:55 +02:00
Ajay Ramachandran
8cce2a5977 Update nginx config 2021-06-14 22:25:24 +02:00
Ajay Ramachandran
e06eb96fa7 Add ability to ban specific category 2021-06-14 16:23:39 -04:00
Michael C
edbbc62e5c add delete to CORS for /api/lockCategories 2021-06-14 13:19:41 -04:00
Nanobyte
bbd478f322 Fix webhook default value
Added missing property and changed all defaults back to null
2021-06-14 10:47:46 +02:00
Ajay Ramachandran
17eb9604e7 Add banned username 2021-06-13 17:13:44 -04:00
Ajay Ramachandran
588e0abdd8 Fix type = 20 vote 2021-06-13 16:22:10 -04:00
Ajay Ramachandran
b08f5c8390 Don't break for incorrect votes 2021-06-13 16:00:36 -04:00
Ajay Ramachandran
344e680fe3 Fix rejections not being seperated 2021-06-09 15:14:31 -04:00
Ajay Ramachandran
4225d9b3b3 Silently reject votes 2021-06-08 20:20:05 -04:00
Ajay Ramachandran
1c8c76831e Make redis not persist 2021-06-04 16:03:18 -04:00
Ajay Ramachandran
912f878906 Print video ID in newleaf errors 2021-06-03 14:49:01 -04:00
Ajay Ramachandran
ec081cf0c5 Support multiple newleaf urls 2021-06-03 11:38:21 -04:00
Ajay Ramachandran
1e5849f504 Prevent failing on api errors 2021-06-03 11:29:55 -04:00
Ajay Ramachandran
10fcc7885f Raise redis memory 2021-06-03 00:50:05 -04:00
Ajay Ramachandran
29665d5a03 Merge pull request #238 from ajayyy/newleaf
Use newleaf instead of YouTube API
2021-06-02 22:41:06 -04:00
Ajay Ramachandran
e7337d3cb4 Add missing dependency 2021-06-02 22:40:18 -04:00
Ajay Ramachandran
0904036009 Use newleaf instead of YouTube API 2021-06-02 22:34:38 -04:00
Ajay Ramachandran
c1609a826a Don't think duration changed when API fails 2021-06-02 19:17:29 -04:00
Ajay Ramachandran
2453c45b06 Don't use undefined lockedSum from cache 2021-06-01 22:20:42 -04:00
Ajay Ramachandran
63c8f87776 Don't deconstruct 2021-06-01 16:18:41 -04:00
Ajay Ramachandran
f20506bf43 Add back youtube api error handling 2021-06-01 16:14:21 -04:00
Ajay Ramachandran
ec51ff835a Consider locked segments when calculating reputation 2021-05-29 20:48:41 -04:00
Ajay Ramachandran
6a58a08781 Rename user info endpoint 2021-05-24 16:05:18 -04:00
Ajay Ramachandran
3f682d467d Fix reputation unit tests 2021-05-24 16:00:45 -04:00
Ajay Ramachandran
676fc8ea08 Add reputation to user info 2021-05-24 15:56:03 -04:00
Ajay Ramachandran
a732159a3a Fix comment in sql upgrade file 2021-05-24 12:46:39 -04:00
Ajay Ramachandran
09fc3ca882 Raise reputation cap and don't count autovote submissions 2021-05-24 12:43:06 -04:00
Ajay Ramachandran
300ee0183e Add a max initial boost 2021-05-24 10:51:32 -04:00
Ajay Ramachandran
d7f352d699 Revert "Don't get reputation every time"
This reverts commit 994dba86f6.
2021-05-23 23:36:16 -04:00
Ajay Ramachandran
994dba86f6 Don't get reputation every time 2021-05-23 23:30:47 -04:00
Ajay Ramachandran
9990e0b807 Merge pull request #236 from ajayyy/segment-sort
Segment sorting
2021-05-23 23:20:42 -04:00
Ajay Ramachandran
30d0cb7590 Don't break with old cached data 2021-05-23 23:19:39 -04:00
Ajay Ramachandran
52b201ff87 Change to vary boost by votes 2021-05-23 21:43:23 -04:00
Ajay Ramachandran
eb2ffff780 Add tests for reputation 2021-05-23 18:51:23 -04:00
Ajay Ramachandran
d3210d4e27 Move files to utils 2021-05-23 18:00:20 -04:00
Ajay Ramachandran
5c2ab9087a Use reputation when sorting segments 2021-05-23 17:54:51 -04:00
Ajay Ramachandran
194c657ba7 Clear reputation cache 2021-05-23 17:05:06 -04:00
Ajay Ramachandran
a5f9c2a022 Don't allow self votes 2021-05-23 16:57:41 -04:00
Ajay Ramachandran
0051022906 remove old user trustworthy code 2021-05-23 16:55:31 -04:00
Ajay Ramachandran
cfcb6c6b64 Add reputation system 2021-05-23 16:53:35 -04:00
Ajay Ramachandran
799aef0b65 Move redis code to middleware 2021-05-23 15:49:12 -04:00
Ajay Ramachandran
1b175d85c0 Update mocha 2021-05-23 14:56:04 -04:00
Ajay Ramachandran
9d19c59d44 Add caching for raw videoID fetching 2021-05-23 12:03:05 -04:00
Ajay Ramachandran
96ccbbe4a2 Removed unnecessary conditionals 2021-05-23 11:35:02 -04:00
Ajay Ramachandran
c7b7732092 Update lodash 2021-05-23 11:27:18 -04:00
Ajay Ramachandran
77da67ce98 Merge pull request #230 from ajayyy/dependabot/npm_and_yarn/redis-3.1.1
Bump redis from 3.0.2 to 3.1.1
2021-05-23 11:26:21 -04:00
Ajay Ramachandran
38360f379f Merge pull request #224 from ajayyy/export
Add highlight category
2021-05-23 11:22:02 -04:00
Ajay Ramachandran
5a60dfa988 Uncomment webhook 2021-05-23 11:19:40 -04:00
Ajay Ramachandran
590ed037dd Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into export 2021-05-23 11:17:10 -04:00
Ajay Ramachandran
e71399f5af Add banned user 2021-05-13 21:24:53 -04:00
Ajay Ramachandran
34aadda47a Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-05-13 14:59:14 -04:00
Ajay Ramachandran
0c64f4b006 Check for array in non hash prefix method 2021-05-13 14:59:12 -04:00
Ajay Ramachandran
72aff3a695 Block username change 2021-05-12 18:57:36 -04:00
Nanobyte
1122681c4f Fix prepare statements and inconsistencies 2021-05-07 02:01:49 +02:00
Nanobyte
78a7f8a207 Fix test case prepare statements 2021-05-07 01:51:11 +02:00
Ajay Ramachandran
60a118f391 Add object src to csp 2021-05-06 16:14:11 -04:00
Ajay Ramachandran
cd66399049 Add csp for API 2021-05-06 16:03:26 -04:00
Ajay Ramachandran
b0a4b6ebed Update indexes file table name 2021-05-06 15:53:31 -04:00
Ajay Ramachandran
99a4ed9e84 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-05-05 17:02:05 -04:00
Ajay Ramachandran
e93c08f33a disable database by default 2021-05-05 17:01:52 -04:00
dependabot[bot]
a47906cac9 Bump redis from 3.0.2 to 3.1.1
Bumps [redis](https://github.com/NodeRedis/node-redis) from 3.0.2 to 3.1.1.
- [Release notes](https://github.com/NodeRedis/node-redis/releases)
- [Changelog](https://github.com/NodeRedis/node-redis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NodeRedis/node-redis/compare/v3.0.2...v3.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-29 22:27:42 +00:00
Ajay Ramachandran
423ea9cbc6 Merge pull request #231 from MRuy/fix/run-tests-in-memory-db
Use in memory database for tests
2021-04-29 18:26:15 -04:00
Nanobyte
35714d4f2d Use in memory database for tests 2021-04-29 21:49:25 +02:00
Ajay Ramachandran
129cf8d02d Merge pull request #229 from MRuy/fix/rename-no-segments
Rename noSegments to lockCategories
2021-04-23 21:34:04 -04:00
Nanobyte
f561388a1f Rename noSegments to lockCategories 2021-04-24 01:54:42 +02:00
Ajay Ramachandran
a587247c0d Don't hold connections open in getTopUsers 2021-04-23 18:21:08 -04:00
Ajay Ramachandran
72121f98de Revert "Lower redis memory"
This reverts commit fe3420a512.
2021-04-22 23:12:44 -04:00
Ajay Ramachandran
0a66dcc0d6 Redirect to cdn 2021-04-23 04:59:36 +02:00
Ajay Ramachandran
a7605d5699 Don't crash for redis errors 2021-04-21 20:17:46 -04:00
Ajay Ramachandran
fe3420a512 Lower redis memory 2021-04-21 20:05:41 -04:00
Ajay Ramachandran
c7e78c21c9 Restart docker containers always 2021-04-21 19:43:32 -04:00
Ajay Ramachandran
228a9a8807 Don't update lastUpdate until the update is complete 2021-04-21 18:49:00 -04:00
Ajay Ramachandran
61b64fa904 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-04-21 18:25:44 -04:00
Ajay Ramachandran
6bcd6e2d80 Don't update multiple times 2021-04-21 18:25:38 -04:00
Ajay Ramachandran
d60e079e50 Merge pull request #227 from MRuy/fix/filter-usernames
Remove unicode control characters from username
2021-04-19 21:06:26 -04:00
Ajay Ramachandran
ecfd9da7a1 Update dump when using redirect urls 2021-04-19 21:03:58 -04:00
Ajay Ramachandran
697f1f47dd Use .csv in dump urls 2021-04-19 20:59:01 -04:00
Ajay Ramachandran
19058d3760 Add redirects 2021-04-19 20:54:52 -04:00
Nanobyte
3a60b6fff7 Remove unicode control characters from username 2021-04-19 03:14:31 +02:00
Ajay Ramachandran
dad4fbca75 Merge pull request #226 from MRuy/fix/getUserInfo
Fix/get user info
2021-04-18 15:55:18 -04:00
Ajay Ramachandran
d56121fdec Merge pull request #210 from MRuy/feat/limit-reward-time-per-segment
Limit reward time per segment
2021-04-18 15:53:34 -04:00
Ajay Ramachandran
a3db0a005a Formatting plus count(*)
https://www.citusdata.com/blog/2016/10/12/count-performance/
2021-04-18 15:53:19 -04:00
Ajay Ramachandran
ddf1fdc89c Merge branch 'master' into feat/limit-reward-time-per-segment 2021-04-18 15:47:42 -04:00
Ajay Ramachandran
e70ae12f2a Fix quote issues 2021-04-18 15:46:46 -04:00
Ajay Ramachandran
b6660d656f Add cdn redirect 2021-04-18 21:10:43 +02:00
Ajay Ramachandran
2814ce7b7f Change dump deletion logic 2021-04-18 12:28:47 -04:00
Ajay Ramachandran
911ebddd69 Fix example config 2021-04-17 23:09:21 -04:00
Ajay Ramachandran
5eacfff7ae Merge pull request #217 from MRuy/feature/configurable-database-dump 2021-04-17 23:07:08 -04:00
Ajay Ramachandran
a06ab724ad Fix file locations + formatting 2021-04-17 23:06:39 -04:00
Ajay Ramachandran
d8e7bf130f Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-04-18 04:50:30 +02:00
Ajay Ramachandran
058c05a1f7 Fix permission issues 2021-04-18 04:49:05 +02:00
Ajay Ramachandran
9d06bda4f8 Don't allow downvoting dead submissions 2021-04-17 16:37:39 -04:00
Ajay Ramachandran
346485da8c Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer
# Conflicts:
#	src/routes/voteOnSponsorTime.ts
2021-04-17 16:25:10 -04:00
Ajay Ramachandran
5b2f05741e Fix no segments votes being allowed 2021-04-17 16:23:45 -04:00
Nanobyte
cb4ecea830 Add vip info to getUserInfo 2021-04-15 23:05:18 +02:00
Nanobyte
112b232f9e Fix UserID types 2021-04-15 23:03:50 +02:00
Nanobyte
9b0ba9031e Optimize code 2021-04-15 01:22:25 +02:00
Nanobyte
389885893c Only get enabled warnings 2021-04-15 01:22:01 +02:00
Ajay Ramachandran
77a4c2fe34 Update nginx config 2021-04-13 03:04:02 +02:00
Ajay Ramachandran
f6f5570d0c Improve auto mod reject message 2021-04-11 13:15:42 -04:00
Ajay Ramachandran
6a9b218e22 Don't always use YouTube API cache 2021-04-08 20:37:19 -04:00
Ajay Ramachandran
8088f37632 Only return one segment for highlight category 2021-04-05 23:48:51 -04:00
Ajay Ramachandran
7bf09906d3 Prevent voting for highlight category 2021-04-05 22:33:28 -04:00
Ajay Ramachandran
6554e142cc Add highlight category 2021-04-04 23:12:26 -04:00
Ajay Ramachandran
bf2d033ac3 Merge pull request #223 from ajayyy/export
Improvements
2021-04-02 16:43:40 -04:00
Ajay Ramachandran
bc688a3d8d FIx duration issue 2021-04-02 16:40:51 -04:00
Ajay Ramachandran
5bcfe9f192 Merge pull request #222 from ajayyy/dependabot/npm_and_yarn/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1
2021-04-02 12:25:14 -04:00
Ajay Ramachandran
cfbf8a47d7 Fix hashing function 2021-04-02 12:03:21 -04:00
dependabot[bot]
1eca55d96c Bump y18n from 4.0.0 to 4.0.1
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-31 21:52:03 +00:00
Ajay Ramachandran
93d7242021 Add preview category 2021-03-30 22:50:09 -04:00
Ajay Ramachandran
612463165a Merge pull request #220 from ajayyy/export
Unlock videos and hide segments if duration changed
2021-03-30 18:28:44 -04:00
Ajay Ramachandran
c9a8dc21b1 Unlock videos and hide segments if duration changed 2021-03-29 19:16:18 -04:00
Ajay Ramachandran
c17f0b1e6e Add invite link 2021-03-29 18:39:55 -04:00
Ajay Ramachandran
e5e63efffe Merge pull request #218 from ajayyy/export
Apply indexes after upgrades
2021-03-26 21:28:26 -04:00
Ajay Ramachandran
5152d7e649 Fixed tests 2021-03-26 19:13:52 -04:00
Ajay Ramachandran
37a07ace72 Cache data for getting hash-prefix segments 2021-03-26 19:03:30 -04:00
Ajay Ramachandran
46524e4298 Fix indexes 2021-03-26 19:02:32 -04:00
Ajay Ramachandran
c7eb5fed35 Fix video duration precision and use submitted one when possible 2021-03-26 18:35:25 -04:00
Ajay Ramachandran
5c827baa1a Update db link 2021-03-25 18:48:44 -04:00
Ajay Ramachandran
27c2562a7f Add more indexes 2021-03-23 23:46:46 -04:00
Nanobyte
2c3dde0d2e Timestamp based dump filenames and garbage collection 2021-03-22 22:18:23 +01:00
Nanobyte
8219b0398e Fix invalid json in example config 2021-03-22 01:35:45 +01:00
Ajay Ramachandran
11b4f642a6 Apply indexes after upgrades 2021-03-21 19:16:56 -04:00
Nanobyte
514ea03655 Add TS for dumpDatabase config 2021-03-21 22:59:16 +01:00
Nanobyte
84b86bb6a1 Make dumpDatabase configurable 2021-03-21 22:40:57 +01:00
Ajay Ramachandran
fcd7be632c Merge pull request #215 from ajayyy/export
Add new "Service" option
2021-03-20 12:26:08 -04:00
Ajay Ramachandran
cbf043ac7e Add twitch 2021-03-20 11:54:50 -04:00
Ajay Ramachandran
180d9bfb73 Add explanation to database page 2021-03-20 11:46:37 -04:00
Ajay Ramachandran
8423165df4 Add json page for database export 2021-03-20 01:13:16 -04:00
Ajay Ramachandran
02e628f533 Setup csv exports and html status page 2021-03-20 01:08:33 -04:00
Ajay Ramachandran
3c89e9c015 Send back duration in getSkipSegments request 2021-03-19 22:52:23 -04:00
Ajay Ramachandran
5544491728 Add duration option when submitting and save duration in DB 2021-03-19 22:45:30 -04:00
Ajay Ramachandran
29d2c9c25e Add new "Service" option 2021-03-19 21:31:16 -04:00
Nanobyte
e883f76e54 Fix quote inconsistency 2021-03-20 01:17:50 +01:00
Ajay Ramachandran
10d445badb Merge branch 'master' into feat/limit-reward-time-per-segment 2021-03-19 20:07:22 -04:00
Ajay Ramachandran
8f2ea30da0 Fix rejecting downvotes 2021-03-19 18:19:45 -04:00
Ajay Ramachandran
a27adffec0 Update README.MD 2021-03-19 18:09:53 -04:00
Ajay Ramachandran
14489e3b4b Merge pull request #214 from ajayyy/export
Send moderator rejected votes to discord anyway
2021-03-19 18:09:01 -04:00
Ajay Ramachandran
3503024fd7 Merge pull request #212 from MRuy/feat/postskipsegments-response-with-new-segments
Return new created segments on success
2021-03-19 18:08:43 -04:00
Ajay Ramachandran
1f01c004ae Send moderator rejected votes to discord anyway 2021-03-19 18:05:33 -04:00
Ajay Ramachandran
cfdb0f4466 Remove index creation from upgraders 2021-03-11 18:55:27 -05:00
Ajay Ramachandran
4168733825 Only count users when asked 2021-03-11 18:40:09 -05:00
Ajay Ramachandran
0c4e4af228 Support uppercase hashes 2021-03-11 18:18:55 -05:00
Ajay Ramachandran
f4cf646f80 Add checks for empty categories after filtering 2021-03-08 22:06:18 -05:00
Ajay Ramachandran
b641a0b0b3 Merge pull request #211 from ajayyy/redis
Postgres
2021-03-08 19:28:05 -05:00
Ajay Ramachandran
a4bbc9f2ba Add pg load file 2021-03-08 19:25:20 -05:00
Ajay Ramachandran
b0c7a6c537 Partially fix getTopUsers 2021-03-08 18:28:41 -05:00
Ajay Ramachandran
eacd9cb6e8 Secure docker containers to local network 2021-03-07 00:37:47 -05:00
Ajay Ramachandran
8729796e87 Make tests pass running with postgres 2021-03-07 00:21:56 -05:00
Ajay Ramachandran
3fe7501802 Support private db with postgres 2021-03-06 19:29:03 -05:00
Ajay Ramachandran
54e69b266d Fix tests 2021-03-06 00:25:18 -05:00
Ajay Ramachandran
44f10b9ff9 Removed some unused logs 2021-03-04 23:30:30 -05:00
Ajay Ramachandran
e9b7eac289 Finish up conversion to use case-sensitive column names 2021-03-04 23:29:01 -05:00
Ajay Ramachandran
2772a9dcc6 Switch to case sensitive and get submitting + getting working 2021-03-04 20:23:05 -05:00
Ajay Ramachandran
1a66be8665 Make schemas work with postgres 2021-03-04 19:44:54 -05:00
Ajay Ramachandran
2c211d4730 Fix preprocessor not being used for initial schema 2021-03-01 22:40:13 -05:00
Ajay Ramachandran
88855ab695 Support schema upgrading with postgres 2021-03-01 22:20:44 -05:00
Ajay Ramachandran
46b42da5bd Update tests to use promises 2021-03-01 21:37:35 -05:00
Nanobyte
da3a5fe787 Return new created segments on success 2021-03-02 02:44:51 +01:00
Ajay Ramachandran
ff4af3786e Switch to postgres + promises 2021-03-01 20:40:31 -05:00
Nanobyte
ac945254d6 Limit reward time for getSavedTimeForUser endpoint 2021-03-02 01:22:02 +01:00
Ajay Ramachandran
9a9038d5e0 Update gitignore 2021-03-01 19:21:59 -05:00
Ajay Ramachandran
fa759ae7b2 Add docker compose for deps 2021-03-01 19:21:27 -05:00
Ajay Ramachandran
f358605f70 Merge pull request #209 from MRuy/fix/valid-json-for-categories-param
Fix getSkipSegmentsByHash requires valid json
2021-02-25 21:56:30 -05:00
Nanobyte
d6ba5684e0 Limit reward time per segment 2021-02-26 01:57:45 +01:00
Nanobyte
09c9b25178 Fix getSkipSegmentsByHash requires valid json
The categories parameter has to be a valid array with strings in JSON format
2021-02-25 19:08:29 +01:00
Ajay Ramachandran
e86f442249 Add YouTube terms info 2021-02-21 21:28:29 -05:00
Ajay Ramachandran
e51ebdcad6 Merge pull request #208 from ajayyy/redis
Remove logging and fix voting error
2021-02-20 22:06:27 -05:00
Ajay Ramachandran
eeaa1614fa Remove logging and fix voting error 2021-02-20 22:06:00 -05:00
Ajay Ramachandran
ef79439557 Merge pull request #207 from ajayyy/redis
Only cache for all categories
2021-02-20 22:03:15 -05:00
Ajay Ramachandran
8c910b67b4 Only cache for all categories 2021-02-20 22:02:57 -05:00
Ajay Ramachandran
993f75d014 Merge pull request #206 from ajayyy/redis
Add redis caching for 404s
2021-02-20 21:18:33 -05:00
Ajay Ramachandran
01d318d902 Add redis caching for 404s 2021-02-20 21:13:46 -05:00
Ajay Ramachandran
157a7743a3 Merge pull request #205 from ajayyy/segment-locking
Unlock segment if VIP downvotes
2021-02-18 22:12:58 -05:00
Ajay Ramachandran
597dff7ac3 Unlock segment if VIP downvotes 2021-02-18 22:09:57 -05:00
Ajay Ramachandran
c4c596bbf4 Merge pull request #204 from ajayyy/segment-locking
Replace VIP starting with 1000 votes with locked submissions
2021-02-18 20:50:13 -05:00
Ajay Ramachandran
e21ebd18a6 Don't ratelimit VIPs 2021-02-18 20:47:26 -05:00
Ajay Ramachandran
57adcd3c65 Replace VIP starting with 1000 votes with locked submissions 2021-02-18 20:24:04 -05:00
Ajay Ramachandran
ae57bfeb89 Merge pull request #203 from ajayyy/segment-locking
Add segment locking
2021-02-18 19:54:29 -05:00
Ajay Ramachandran
ef21ceb332 Add segment locking 2021-02-18 19:48:36 -05:00
Ajay Ramachandran
53ae826186 Allow upvotes on locked videos and update message 2021-02-09 19:53:39 -05:00
Ajay Ramachandran
b040db24d4 Fix /news redirect 2021-01-30 11:35:03 -05:00
Ajay Ramachandran
f9f7870c0d Add /viewer redirect 2021-01-30 11:32:37 -05:00
Ajay Ramachandran
51a5e97e11 nginx config update 2021-01-28 19:34:35 -05:00
Ajay Ramachandran
69f95e6398 Fix vote rejection and update warning message 2021-01-26 20:44:32 -05:00
Ajay Ramachandran
10fa36ccf0 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2021-01-24 12:45:20 -05:00
Ajay Ramachandran
3b24dfd4c5 Fix unwarn not working 2021-01-24 12:45:13 -05:00
Ajay Ramachandran
21673c1ee9 fix broken invidious proxy 2021-01-23 12:58:11 -05:00
Ajay Ramachandran
8d15166931 Fix invidious 2021-01-23 12:52:54 -05:00
Ajay Ramachandran
ebc580ea76 Add nignx config file 2021-01-23 12:48:22 -05:00
Ajay Ramachandran
4561148ab2 Fix headers when using node-fetch 2021-01-17 21:18:22 -05:00
Ajay Ramachandran
acc9537bb7 Merge pull request #201 from MRuy/remove-dependency-request
#177 Replace request with node-fetch
2021-01-17 21:05:10 -05:00
Ajay Ramachandran
0bb4ff8417 Merge pull request #200 from ajayyy/improve-types
Improve Types
2021-01-17 15:15:37 -05:00
Nanobyte
314a7b9c56 Remove dependency request 2021-01-06 01:43:52 +01:00
Nanobyte
797e0b4641 Fix test cases 2021-01-06 01:43:28 +01:00
Nanobyte
87d2827f0f Fix errors 2021-01-05 01:22:02 +01:00
Nanobyte
aabeb5f493 Replace request with node-fetch 2021-01-05 01:18:34 +01:00
Ajay Ramachandran
7f0a35c88a Fix type issues 2020-12-29 15:12:18 -05:00
Ajay Ramachandran
29ef770759 Add type safety to getSkipSegments 2020-12-29 14:16:11 -05:00
Ajay Ramachandran
5927a24f16 Merge pull request #199 from ajayyy/delete-warnings
Warning fixes
2020-12-29 13:54:32 -05:00
Ajay Ramachandran
432cc42cba Don't allow duplicate warnings 2020-12-29 13:31:15 -05:00
Ajay Ramachandran
baa4e73ba5 Don't remove all warnings 2020-12-29 13:27:54 -05:00
Ajay Ramachandran
eac6856c1d Merge pull request #198 from ajayyy/delete-warnings
Add remove feature to warnUser
2020-12-29 00:33:14 -05:00
Ajay Ramachandran
78ef129634 Add remove feature to warnUser 2020-12-29 00:18:50 -05:00
Ajay Ramachandran
2769acecc0 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer 2020-12-28 23:40:51 -05:00
Ajay Ramachandran
7beb521d68 Warning should not hash the reported userID 2020-12-28 19:01:23 -05:00
Ajay Ramachandran
30823b752d Add shadowHidden type 2020-12-28 18:57:57 -05:00
Ajay Ramachandran
e3e9c89a80 Better fix for cache type error 2020-12-28 18:50:47 -05:00
Ajay Ramachandran
bb7cc60118 fix crash when variable missing from cache 2020-12-28 18:47:51 -05:00
Ajay Ramachandran
63c3b1f56b Updated warning message 2020-12-28 17:39:16 -05:00
Ajay Ramachandran
561d7bcc42 Merge pull request #188 from opl-/feat/faster-segments
Improve performance of segment querying endpoints
2020-12-24 21:50:57 -05:00
Ajay Ramachandran
e1a9004ed5 Commit missing type file 2020-12-24 21:38:15 -05:00
Ajay Ramachandran
71aa7ec0ef Remove extra js test 2020-12-24 21:29:45 -05:00
Ajay Ramachandran
8129a488a9 Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into feat/faster-segments
# Conflicts:
#	src/routes/getSkipSegments.ts
#	src/routes/getSkipSegmentsByHash.ts
#	test/cases/getSegmentsByHash.js
2020-12-24 21:27:08 -05:00
Ajay Ramachandran
5c4980ed2f Merge pull request #197 from ajayyy/work
Don't hide submissions from locked videos when banning
2020-12-23 00:24:35 -05:00
Ajay Ramachandran
229da1f62d Don't hide submissions from locked videos when banning 2020-12-23 00:22:52 -05:00
Ajay Ramachandran
cb0906a52d Remove minimum sponsor duration for VIP 2020-12-20 13:52:22 -05:00
Ajay Ramachandran
5f4cb63324 Merge pull request #196 from ajayyy/testing
Fix redis type issues
2020-12-17 00:38:21 -05:00
Ajay Ramachandran
8cf3caa77e Only pass error if it exists 2020-12-17 00:28:31 -05:00
Ajay Ramachandran
475c8c594a Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into testing 2020-12-17 00:25:55 -05:00
Ajay Ramachandran
c8d5cec338 Fix redis type issues 2020-12-17 00:25:33 -05:00
Ajay Ramachandran
f5bd1c1eb9 Merge pull request #195 from ajayyy/no-segments-fix
Voting fixes
2020-12-17 00:02:32 -05:00
Ajay Ramachandran
a7f04ad732 Update category test + fix double voting issue
Fix #190
2020-12-16 23:47:47 -05:00
Ajay Ramachandran
5deda4603e Allow submitter to change category immediately 2020-12-16 23:00:11 -05:00
Ajay Ramachandran
cd373f4bca Don't allow votes on locked videos 2020-12-16 22:53:49 -05:00
Ajay Ramachandran
9797d7450c Fix issues caused by YouTube API upgrade 2020-12-16 22:53:25 -05:00
Ajay Ramachandran
f8be719dc1 Merge pull request #194 from ajayyy/dependabot/npm_and_yarn/ini-1.3.7
Bump ini from 1.3.5 to 1.3.7
2020-12-14 01:00:57 -05:00
dependabot[bot]
122efc00fc Bump ini from 1.3.5 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 15:59:18 +00:00
Ajay Ramachandran
1f699ac1d1 Merge pull request #174 from Dainius14/master
migrate to typescript
2020-12-07 17:41:14 -05:00
Ajay Ramachandran
2cd78d5d2f Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into Dainius14/master
# Conflicts:
#	src/routes/shadowBanUser.js
#	src/routes/voteOnSponsorTime.ts
#	test/cases/getSkipSegments.js
#	test/cases/voteOnSponsorTime.js
2020-12-07 17:35:15 -05:00
opl-
0bac7e8d90 Improve performance of segment querying endpoints 2020-12-02 15:20:42 +01:00
Dainius Dauksevicius
7da9de9991 fix nodemon to watch .ts files 2020-11-01 17:29:57 +02:00
Dainius Dauksevicius
12729b36fb fix docker build, add proper mocks to tests, remove YouTubeAPI dependency on youtube test mock, move index.ts and test.ts to /src ant /test folders 2020-10-26 19:13:30 +02:00
Dainius Daukševičius
62b008e693 remove TODO comments 2020-10-26 19:13:30 +02:00
Dainius Daukševičius
08d27265fc migrate to typescript 2020-10-26 19:13:30 +02:00
278 changed files with 24964 additions and 7413 deletions

17
.editorconfig Normal file
View File

@@ -0,0 +1,17 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,json,ts,tsx}]
charset = utf-8
indent_style = space
indent_size = 4
[package.json]
indent_size = 2

32
.eslintrc.js Normal file
View File

@@ -0,0 +1,32 @@
module.exports = {
env: {
browser: false,
es2021: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 12,
sourceType: "module",
},
plugins: ["@typescript-eslint"],
rules: {
// TODO: Remove warn rules when not needed anymore
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"indent": ["warn", 4, { "SwitchCase": 1 }],
"no-multiple-empty-lines": ["error", { max: 2, maxEOF: 0 }],
"no-self-assign": "off",
"no-trailing-spaces": "warn",
"object-curly-spacing": ["warn", "always"],
"prefer-template": "warn",
"quotes": ["warn", "double", { "avoidEscape": true, "allowTemplateLiterals": true }],
"require-await": "warn",
"semi": "warn",
"no-console": "warn"
},
};

View File

@@ -1,18 +1,21 @@
name: CI
name: SQLite CI
on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
jobs:
build:
name: Run Tests
test:
name: Run Tests with SQLite
runs-on: ubuntu-latest
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm install
- name: Run Tests
timeout-minutes: 5
run: npm test

18
.github/workflows/db-backup.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Docker image builds
on:
push:
branches:
- master
paths:
- containers/backup-db/**
workflow_dispatch:
jobs:
backup-db:
uses: ./.github/workflows/docker-build.yml
with:
name: "db-backup"
username: "ajayyy"
folder: "./containers/backup-db"
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

46
.github/workflows/docker-build.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
# Based on https://github.com/ajayyy/sb-mirror/blob/main/.github/workflows/docker-build.yml
name: multi-build-docker
on:
workflow_call:
inputs:
name:
required: true
type: string
username:
required: true
type: string
folder:
required: true
type: string
secrets:
GH_TOKEN:
required: true
jobs:
build_container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
ghcr.io/${{ inputs.username }}/${{ inputs.name }}
tags: |
type-raw,value=alpine
flavor: |
latest=true
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GH_TOKEN }}
- name: push
uses: docker/build-push-action@v3
with:
context: ${{ inputs.folder }}
push: true
tags: ${{ steps.meta.outputs.tags }}

21
.github/workflows/eslint.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Linting
on:
push:
branches:
- master
pull_request:
jobs:
lint:
name: Lint with ESLint
runs-on: ubuntu-latest
steps:
# Initialization
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm install
- name: Run Tests
timeout-minutes: 5
run: npm run lint

View File

@@ -0,0 +1,28 @@
name: create-sqlite-base
on:
push:
branches:
- master
paths:
- databases/**
jobs:
make-base-db:
name: Generate SQLite base .db
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm install
- name: Set config
run: |
echo '{"mode": "init-db-and-exit"}' > config.json
- name: Run Server
timeout-minutes: 10
run: npm start
- uses: actions/upload-artifact@v2
with:
name: SponsorTimesDB.db
path: databases/sponsorTimes.db

29
.github/workflows/postgres-redis-ci.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: PostgreSQL + Redis CI
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Run Tests with PostgreSQL and Redis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the docker-compose stack
env:
PG_USER: ci_db_user
PG_PASS: ci_db_pass
run: docker-compose -f docker/docker-compose-ci.yml up -d
- name: Check running containers
run: docker ps
- uses: actions/setup-node@v2
- run: npm install
- name: Run Tests
env:
TEST_POSTGRES: true
timeout-minutes: 5
run: npm test

25
.github/workflows/sb-server.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Docker image builds
on:
push:
branches:
- master
workflow_dispatch:
jobs:
sb-server:
uses: ./.github/workflows/docker-build.yml
with:
name: "sb-server"
username: "ajayyy"
folder: "."
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
rsync-host:
needs: sb-server
uses: ./.github/workflows/docker-build.yml
with:
name: "rsync-host"
username: "ajayyy"
folder: "./containers/rsync"
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

12
.github/workflows/take-action.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
name: Assign issue to contributor
on: [issue_comment]
jobs:
assign:
name: Take an issue
runs-on: ubuntu-latest
steps:
- name: take the issue
uses: bdougie/take-action@main
env:
GITHUB_TOKEN: ${{ github.token }}

80
.gitignore vendored
View File

@@ -2,47 +2,9 @@
logs
*.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
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
@@ -53,53 +15,33 @@ typings/
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.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/sponsorTimes.db
databases/sponsorTimes.db-shm
databases/sponsorTimes.db-wal
databases/private.db
databases/private.db-shm
databases/private.db-wal
databases/sponsorTimesReal.db
test/databases/sponsorTimes.db
test/databases/sponsorTimes.db-shm
test/databases/sponsorTimes.db-wal
test/databases/private.db
databases/cache
docker/database-export
# Config files
config.json
docker/database.env
# Other
working
# Mac files
.DS_Store
.DS_Store
/.idea/
/dist/

283
DatabaseSchema.md Normal file
View File

@@ -0,0 +1,283 @@
# SponsorTimesDB
[vipUsers](#vipUsers)
[sponsorTimes](#sponsorTimes)
[userNames](#userNames)
[categoryVotes](#categoryVotes)
[lockCategories](#lockCategories)
[warnings](#warnings)
[shadowBannedUsers](#shadowBannedUsers)
[unlistedVideos](#unlistedVideos)
[config](#config)
[archivedSponsorTimes](#archivedSponsorTimes)
### vipUsers
| Name | Type | |
| -- | :--: | -- |
| userID | TEXT | not null |
| index | field |
| -- | :--: |
| vipUsers_index | userID |
### sponsorTimes
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| startTime | REAL | not null |
| endTime | REAL | not null |
| votes | INTEGER | not null |
| locked | INTEGER | not null, default '0' |
| incorrectVotes | INTEGER | not null, default 1 |
| UUID | TEXT | not null, unique |
| userID | TEXT | not null |
| timeSubmitted | INTEGER | not null |
| views | INTEGER | not null |
| category | TEXT | not null, default 'sponsor' |
| actionType | TEXT | not null, default 'skip' |
| service | TEXT | not null, default 'YouTube' |
| videoDuration | INTEGER | not null, default '0' |
| hidden | INTEGER | not null, default '0' |
| reputation | REAL | not null, default '0' |
| shadowHidden | INTEGER | not null |
| hashedVideoID | TEXT | not null, default '', sha256 |
| userAgent | TEXT | not null, default '' |
| description | TEXT | not null, default '' |
| index | field |
| -- | :--: |
| sponsorTime_timeSubmitted | timeSubmitted |
| sponsorTime_userID | userID |
| sponsorTimes_UUID | UUID |
| sponsorTimes_hashedVideoID | hashedVideoID, category |
| sponsorTimes_videoID | videoID, service, category, timeSubmitted |
### userNames
| Name | Type | |
| -- | :--: | -- |
| userID | TEXT | not null |
| userName | TEXT | not null |
| locked | INTEGER | not nul, default '0' |
| index | field |
| -- | :--: |
| userNames_userID | userID |
### categoryVotes
| Name | Type | |
| -- | :--: | -- |
| UUID | TEXT | not null |
| category | TEXT | not null |
| votes | INTEGER | not null, default 0 |
| index | field |
| -- | :--: |
| categoryVotes_UUID_public | UUID, category |
### lockCategories
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| userID | TEXT | not null |
| actionType | TEXT | not null, default 'skip' |
| category | TEXT | not null |
| hashedVideoID | TEXT | not null, default '' |
| reason | TEXT | not null, default '' |
| service | TEXT | not null, default 'YouTube' |
| index | field |
| -- | :--: |
| lockCategories_videoID | videoID, service, category |
### warnings
| Name | Type | |
| -- | :--: | -- |
| userID | TEXT | not null |
| issueTime | INTEGER | not null |
| issuerUserID | TEXT | not null |
| enabled | INTEGER | not null |
| reason | TEXT | not null, default '' |
| index | field |
| -- | :--: |
| warnings_index | userID |
| warnings_issueTime | issueTime |
### shadowBannedUsers
| Name | Type | |
| -- | :--: | -- |
| userID | TEXT | not null |
| index | field |
| -- | :--: |
| shadowBannedUsers_index | userID |
### videoInfo
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| channelID | TEXT | not null |
| title | TEXT | not null |
| published | REAL | not null |
| genreUrl | TEXT | not null |
| index | field |
| -- | :--: |
| videoInfo_videoID | timeSubmitted |
| videoInfo_channelID | userID |
### unlistedVideos
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| year | TEXT | not null |
| views | TEXT | not null |
| channelID | TEXT | not null |
| timeSubmitted | INTEGER | not null |
| service | TEXT | not null, default 'YouTube' |
### config
| Name | Type | |
| -- | :--: | -- |
| key | TEXT | not null, unique |
| value | TEXT | not null |
### archivedSponsorTimes
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| startTime | REAL | not null |
| endTime | REAL | not null |
| votes | INTEGER | not null |
| locked | INTEGER | not null, default '0' |
| incorrectVotes | INTEGER | not null, default 1 |
| UUID | TEXT | not null, unique |
| userID | TEXT | not null |
| timeSubmitted | INTEGER | not null |
| views | INTEGER | not null |
| category | TEXT | not null, default 'sponsor' |
| actionType | TEXT | not null, default 'skip' |
| service | TEXT | not null, default 'YouTube' |
| videoDuration | INTEGER | not null, default '0' |
| hidden | INTEGER | not null, default '0' |
| reputation | REAL | not null, default '0' |
| shadowHidden | INTEGER | not null |
| hashedVideoID | TEXT | not null, default '', sha256 |
| userAgent | TEXT | not null, default '' |
### ratings
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| service | TEXT | not null, default 'YouTube' |
| type | INTEGER | not null |
| count | INTEGER | not null |
| hashedVideoID | TEXT | not null |
| index | field |
| -- | :--: |
| ratings_hashedVideoID_gin | hashedVideoID |
| ratings_hashedVideoID | hashedVideoID, service |
| ratings_videoID | videoID, service |
# Private
[votes](#votes)
[categoryVotes](#categoryVotes)
[sponsorTimes](#sponsorTimes)
[config](#config)
[ratings](#ratings)
[tempVipLog](#tempVipLog)
[userNameLogs](#userNameLogs)
### votes
| Name | Type | |
| -- | :--: | -- |
| UUID | TEXT | not null |
| userID | TEXT | not null |
| hashedIP | TEXT | not null |
| type | INTEGER | not null |
| index | field |
| -- | :--: |
| votes_userID | UUID |
### categoryVotes
| Name | Type | |
| -- | :--: | -- |
| UUID | TEXT | not null |
| userID | TEXT | not null |
| hashedIP | TEXT | not null |
| category | TEXT | not null |
| timeSubmitted | INTEGER | not null |
| index | field |
| -- | :--: |
| categoryVotes_UUID | UUID, userID, hasedIP, category |
### sponsorTimes
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| hashedIP | TEXT | not null |
| timeSubmitted | INTEGER | not null |
| service | TEXT | not null, default 'YouTube' |
| index | field |
| -- | :--: |
| sponsorTimes_hashedIP | hashedIP |
| privateDB_sponsorTimes_videoID_v2 | videoID, service |
### config
| Name | Type | |
| -- | :--: | -- |
| key | TEXT | not null |
| value | TEXT | not null |
### ratings
| Name | Type | |
| -- | :--: | -- |
| videoID | TEXT | not null |
| service | TEXT | not null, default 'YouTube' |
| userID | TEXT | not null |
| type | INTEGER | not null |
| timeSubmitted | INTEGER | not null |
| hashedIP | TEXT | not null |
| index | field |
| -- | :--: |
| ratings_videoID | videoID, service, userID, timeSubmitted |
### tempVipLog
| Name | Type | |
| -- | :--: | -- |
| issuerUserID | TEXT | not null |
| targetUserID | TEXT | not null |
| enabled | BOOLEAN | not null |
| updatedAt | INTEGER | not null |
### userNameLogs
| Name | Type | |
| -- | :--: | -- |
| userID | TEXT | not null |
| newUserName | TEXT | not null |
| oldUserName | TEXT | not null |
| updatedByAdmin | BOOLEAN | not null |
| updatedAt | INTEGER | not null |

View File

@@ -1,11 +1,16 @@
FROM node:12
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY index.js .
FROM node:16-alpine as builder
RUN apk add --no-cache --virtual .build-deps python3 make g++
COPY package.json package-lock.json tsconfig.json entrypoint.sh ./
COPY src src
RUN mkdir databases
COPY databases/*.sql databases/
RUN npm ci && npm run tsc
FROM node:16-alpine as app
WORKDIR /usr/src/app
RUN apk add git postgresql-client
COPY --from=builder ./node_modules ./node_modules
COPY --from=builder ./dist ./dist
COPY ./.git ./.git
COPY entrypoint.sh .
COPY databases/*.sql databases/
EXPOSE 8080
CMD ./entrypoint.sh

View File

@@ -6,9 +6,9 @@ This is the server backend for it
# Server
This is a simple Sqlite database that will hold all the timing data.
This uses a Postgres or Sqlite database to hold all the timing data.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db. You can download a backup or get archive.org to take a backup if you do desire. The database is under [this license](https://creativecommons.org/licenses/by-nc-sa/4.0/) unless you get explicit permission from me.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database. You can download a backup or get archive.org to take a backup if you do desire. The database is under [this license](https://creativecommons.org/licenses/by-nc-sa/4.0/) unless you get explicit permission from me.
Hopefully this project can be combined with projects like [this](https://github.com/Sponsoff/sponsorship_remover) and use this data to create a neural network to predict when sponsored segments happen. That project is sadly abandoned now, so I have decided to attempt to revive this idea.
@@ -34,4 +34,4 @@ If you want to make changes, run `npm run dev` to automatically reload the serve
# API Docs
Available [here](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs)
Available [here](https://wiki.sponsor.ajay.app/index.php/API_Docs)

71
ci.json Normal file
View File

@@ -0,0 +1,71 @@
{
"port": 8080,
"mockPort": 8081,
"globalSalt": "testSalt",
"adminUserID": "4bdfdc9cddf2c7d07a8a87b57bf6d25389fb75d1399674ee0e0938a6a60f4c3b",
"newLeafURLs": ["placeholder"],
"discordReportChannelWebhookURL": "http://127.0.0.1:8081/ReportChannelWebhook",
"discordFirstTimeSubmissionsWebhookURL": "http://127.0.0.1:8081/FirstTimeSubmissionsWebhook",
"discordCompletelyIncorrectReportWebhookURL": "http://127.0.0.1:8081/CompletelyIncorrectReportWebhook",
"discordNeuralBlockRejectWebhookURL": "http://127.0.0.1:8081/NeuralBlockRejectWebhook",
"neuralBlockURL": "http://127.0.0.1:8081/NeuralBlock",
"behindProxy": true,
"postgres": {
"user": "ci_db_user",
"password": "ci_db_pass",
"host": "localhost",
"port": 5432
},
"redis": {
"socket": {
"host": "localhost",
"port": 6379
}
},
"createDatabaseIfNotExist": true,
"schemaFolder": "./databases",
"dbSchema": "./databases/_sponsorTimes.db.sql",
"privateDBSchema": "./databases/_private.db.sql",
"categoryList": ["sponsor", "selfpromo", "exclusive_access", "interaction", "intro", "outro", "preview", "music_offtopic", "filler", "poi_highlight", "chapter"],
"mode": "test",
"readOnly": false,
"webhooks": [
{
"url": "http://127.0.0.1:8081/CustomWebhook",
"key": "superSecretKey",
"scopes": [
"vote.up",
"vote.down"
]
}, {
"url": "http://127.0.0.1:8081/FailedWebhook",
"key": "superSecretKey",
"scopes": [
"vote.up",
"vote.down"
]
}, {
"url": "http://127.0.0.1:8099/WrongPort",
"key": "superSecretKey",
"scopes": [
"vote.up",
"vote.down"
]
}
],
"maxNumberOfActiveWarnings": 3,
"hoursAfterWarningExpires": 24,
"rateLimit": {
"vote": {
"windowMs": 900000,
"max": 20,
"message": "Too many votes, please try again later",
"statusCode": 429
},
"view": {
"windowMs": 900000,
"max": 20,
"statusCode": 200
}
}
}

View File

@@ -4,7 +4,7 @@
"port": 80,
"globalSalt": "[global salt (pepper) that is added to every ip before hashing to make it even harder for someone to decode the ip]",
"adminUserID": "[the hashed id of the user who can perform admin actions]",
"youtubeAPIKey": null, //get this from Google Cloud Platform [optional]
"newLeafURLs": ["http://localhost:3241"],
"discordReportChannelWebhookURL": null, //URL from discord if you would like notifications when someone makes a report [optional]
"discordFirstTimeSubmissionsWebhookURL": null, //URL from discord if you would like notifications when someone makes a first time submission [optional]
"discordCompletelyIncorrectReportWebhookURL": null, //URL from discord if you would like notifications when someone reports a submission as completely incorrect [optional]
@@ -19,10 +19,11 @@
"schemaFolder": "./databases",
"dbSchema": "./databases/_sponsorTimes.db.sql",
"privateDBSchema": "./databases/_private.db.sql",
// when using redis, add `"enable_offline_queue": false` to force commands to fail instead of timing out
"mode": "development",
"readOnly": false,
"webhooks": [],
"categoryList": ["sponsor", "intro", "outro", "interaction", "selfpromo", "music_offtopic"], // List of supported categories any other category will be rejected
"categoryList": ["sponsor", "intro", "outro", "interaction", "selfpromo", "preview", "music_offtopic", "poi_highlight"], // List of supported categories any other category will be rejected
"getTopUsersCacheTimeMinutes": 5, // cacheTime for getTopUsers result in minutes
"maxNumberOfActiveWarnings": 3, // Users with this number of warnings will be blocked until warnings expire
"hoursAfterWarningExpire": 24,
@@ -38,5 +39,32 @@
"max": 20, // 20 requests in 15min time window
"statusCode": 200
}
},
"maxRewardTimePerSegmentInSeconds": 86400, // maximum time a user get rewarded in the leaderboard for a single segment
"dumpDatabase": {
"enabled": true,
"minTimeBetweenMs": 60000, // 1 minute between dumps
"appExportPath": "./docker/database-export",
"postgresExportPath": "/opt/exports",
"tables": [{
"name": "sponsorTimes",
"order": "timeSubmitted"
},
{
"name": "userNames"
},
{
"name": "categoryVotes"
},
{
"name": "lockCategories"
},
{
"name": "warnings",
"order": "issueTime"
},
{
"name": "vipUsers"
}]
}
}

View File

@@ -0,0 +1,13 @@
FROM alpine
RUN apk add postgresql-client
RUN apk add restic --repository http://dl-cdn.alpinelinux.org/alpine/latest-stable/community/
COPY ./backup.sh /usr/src/app/backup.sh
RUN chmod +x /usr/src/app/backup.sh
COPY ./backup.sh /usr/src/app/forget.sh
RUN chmod +x /usr/src/app/forget.sh
RUN echo '30 * * * * /usr/src/app/backup.sh' >> /etc/crontabs/root
RUN echo '10 0 * * 1 /usr/src/app/forget.sh' >> /etc/crontabs/root
CMD crond -l 2 -f

View File

@@ -0,0 +1,6 @@
mkdir ./dump
pg_dump -f ./dump/sponsorTimes.dump sponsorTimes
pg_dump -f ./dump/privateDB.dump privateDB
restic backup ./dump

View File

@@ -0,0 +1 @@
restic forget --prune --keep-last 48 --keep-daily 7 --keep-weekly 8

View File

@@ -0,0 +1,6 @@
FROM ghcr.io/ajayyy/sb-server:latest
EXPOSE 873/tcp
RUN apk add rsync>3.2.4-r0
RUN mkdir /usr/src/app/database-export
CMD rsync --no-detach --daemon & ./entrypoint.sh

View File

@@ -1,8 +1,5 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "shadowBannedUsers" (
"userID" TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS "votes" (
"UUID" TEXT NOT NULL,
"userID" TEXT NOT NULL,
@@ -29,7 +26,4 @@ CREATE TABLE IF NOT EXISTS "config" (
"value" TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS sponsorTimes_hashedIP on sponsorTimes(hashedIP);
CREATE INDEX IF NOT EXISTS votes_userID on votes(UUID);
COMMIT;

View File

@@ -0,0 +1,26 @@
-- sponsorTimes
CREATE INDEX IF NOT EXISTS "privateDB_sponsorTimes_v4"
ON public."sponsorTimes" USING btree
("videoID" ASC NULLS LAST, service COLLATE pg_catalog."default" ASC NULLS LAST, "timeSubmitted" ASC NULLS LAST);
-- votes
CREATE INDEX IF NOT EXISTS "votes_userID"
ON public.votes USING btree
("UUID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- categoryVotes
CREATE INDEX IF NOT EXISTS "categoryVotes_UUID"
ON public."categoryVotes" USING btree
("UUID" COLLATE pg_catalog."default" ASC NULLS LAST, "userID" COLLATE pg_catalog."default" ASC NULLS LAST, "hashedIP" COLLATE pg_catalog."default" ASC NULLS LAST, category COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- ratings
CREATE INDEX IF NOT EXISTS "ratings_videoID"
ON public."ratings" USING btree
("videoID" COLLATE pg_catalog."default" ASC NULLS LAST, service COLLATE pg_catalog."default" ASC NULLS LAST, "userID" COLLATE pg_catalog."default" ASC NULLS LAST, "timeSubmitted" ASC NULLS LAST)
TABLESPACE pg_default;

View File

@@ -3,6 +3,11 @@ BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "vipUsers" (
"userID" TEXT NOT NULL
);
COMMIT;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "sponsorTimes" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
@@ -12,25 +17,27 @@ CREATE TABLE IF NOT EXISTS "sponsorTimes" (
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL,
"category" TEXT NOT NULL,
"shadowHidden" INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS "userNames" (
"userID" TEXT NOT NULL,
"userName" TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS "categoryVotes" (
"UUID" TEXT NOT NULL,
"category" TEXT NOT NULL,
"votes" INTEGER NOT NULL default '0'
"votes" INTEGER NOT NULL default 0
);
CREATE TABLE IF NOT EXISTS "config" (
"key" TEXT NOT NULL UNIQUE,
"key" TEXT NOT NULL UNIQUE,
"value" TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS sponsorTimes_videoID on sponsorTimes(videoID);
CREATE INDEX IF NOT EXISTS sponsorTimes_UUID on sponsorTimes(UUID);
CREATE EXTENSION IF NOT EXISTS pgcrypto; --!sqlite-ignore
CREATE EXTENSION IF NOT EXISTS pg_trgm; --!sqlite-ignore
COMMIT;

View File

@@ -0,0 +1,106 @@
-- sponsorTimes
CREATE INDEX IF NOT EXISTS "sponsorTime_timeSubmitted"
ON public."sponsorTimes" USING btree
("timeSubmitted" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "sponsorTime_userID"
ON public."sponsorTimes" USING btree
("userID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "sponsorTimes_UUID"
ON public."sponsorTimes" USING btree
("UUID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "sponsorTimes_hashedVideoID"
ON public."sponsorTimes" USING btree
(service COLLATE pg_catalog."default" ASC NULLS LAST, "hashedVideoID" text_pattern_ops ASC NULLS LAST, "startTime" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "sponsorTimes_videoID"
ON public."sponsorTimes" USING btree
(service COLLATE pg_catalog."default" ASC NULLS LAST, "videoID" COLLATE pg_catalog."default" ASC NULLS LAST, "startTime" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "sponsorTimes_description_gin"
ON public."sponsorTimes" USING gin
("description" COLLATE pg_catalog."default" gin_trgm_ops, category COLLATE pg_catalog."default" gin_trgm_ops)
TABLESPACE pg_default;
-- userNames
CREATE INDEX IF NOT EXISTS "userNames_userID"
ON public."userNames" USING btree
("userID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- vipUsers
CREATE INDEX IF NOT EXISTS "vipUsers_index"
ON public."vipUsers" USING btree
("userID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- warnings
CREATE INDEX IF NOT EXISTS "warnings_index"
ON public.warnings USING btree
("userID" COLLATE pg_catalog."default" ASC NULLS LAST, "issueTime" DESC NULLS LAST, enabled DESC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "warnings_issueTime"
ON public.warnings USING btree
("issueTime" ASC NULLS LAST)
TABLESPACE pg_default;
-- lockCategories
CREATE INDEX IF NOT EXISTS "lockCategories_videoID"
ON public."lockCategories" USING btree
("videoID" COLLATE pg_catalog."default" ASC NULLS LAST, service COLLATE pg_catalog."default" ASC NULLS LAST, category COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- categoryVotes
CREATE INDEX IF NOT EXISTS "categoryVotes_UUID_public"
ON public."categoryVotes" USING btree
("UUID" COLLATE pg_catalog."default" ASC NULLS LAST, category COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- shadowBannedUsers
CREATE INDEX IF NOT EXISTS "shadowBannedUsers_index"
ON public."shadowBannedUsers" USING btree
("userID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- videoInfo
CREATE INDEX IF NOT EXISTS "videoInfo_videoID"
ON public."videoInfo" USING btree
("videoID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "videoInfo_channelID"
ON public."videoInfo" USING btree
("channelID" COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
-- ratings
CREATE INDEX IF NOT EXISTS "ratings_hashedVideoID_gin"
ON public."ratings" USING gin
("hashedVideoID" COLLATE pg_catalog."default" gin_trgm_ops)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "ratings_hashedVideoID"
ON public."ratings" USING btree
("hashedVideoID" COLLATE pg_catalog."default" ASC NULLS LAST, service COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;
CREATE INDEX IF NOT EXISTS "ratings_videoID"
ON public."ratings" USING btree
("videoID" COLLATE pg_catalog."default" ASC NULLS LAST, service COLLATE pg_catalog."default" ASC NULLS LAST)
TABLESPACE pg_default;

View File

@@ -3,6 +3,6 @@ BEGIN TRANSACTION;
/* for testing the db upgrade, don't remove because it looks empty */
/* Add version to config */
INSERT INTO config (key, value) VALUES("version", 1);
INSERT INTO config (key, value) VALUES('version', 1);
COMMIT;

View File

@@ -0,0 +1,13 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "userNameLogs" (
"userID" TEXT NOT NULL,
"newUserName" TEXT NOT NULL,
"oldUserName" TEXT NOT NULL,
"updatedByAdmin" BOOLEAN NOT NULL,
"updatedAt" INTEGER NOT NULL
);
UPDATE "config" SET value = 2 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,10 @@
BEGIN TRANSACTION;
ALTER TABLE "sponsorTimes" ADD "service" TEXT NOT NULL default 'YouTube';
-- UPDATE "sponsorTimes" SET "service" = "YouTube";
DROP INDEX IF EXISTS "privateDB_sponsorTimes_videoID";
UPDATE "config" SET value = 3 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,14 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "ratings" (
"videoID" TEXT NOT NULL,
"service" TEXT NOT NULL default 'YouTube',
"type" INTEGER NOT NULL,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"hashedIP" TEXT NOT NULL
);
UPDATE "config" SET value = 4 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,12 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "tempVipLog" (
"issuerUserID" TEXT NOT NULL,
"targetUserID" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL,
"updatedAt" INTEGER NOT NULL
);
UPDATE "config" SET value = 5 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,7 @@
BEGIN TRANSACTION;
DROP INDEX IF EXISTS "sponsorTimes_hashedIP", "privateDB_sponsorTimes_videoID_v2"; --!sqlite-ignore
UPDATE "config" SET value = 6 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,7 @@
BEGIN TRANSACTION;
ALTER TABLE "votes" ADD "normalUserID" TEXT NOT NULL default '';
UPDATE "config" SET value = 7 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,15 @@
BEGIN TRANSACTION;
-- Add primary keys
ALTER TABLE "userNameLogs" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "categoryVotes" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "sponsorTimes" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "config" ADD PRIMARY KEY ("key"); --!sqlite-ignore
ALTER TABLE "ratings" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "tempVipLog" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "votes" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
UPDATE "config" SET value = 8 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,9 @@
BEGIN TRANSACTION;
-- Add primary keys
DROP INDEX IF EXISTS "privateDB_sponsorTimes_v3"; --!sqlite-ignore
UPDATE "config" SET value = 9 WHERE key = 'version';
COMMIT;

View File

@@ -6,20 +6,20 @@ CREATE TABLE "sqlb_temp_table_1" (
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"incorrectVotes" INTEGER NOT NULL default '1',
"incorrectVotes" INTEGER NOT NULL default 1,
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT "sponsor",
"category" TEXT NOT NULL DEFAULT 'sponsor',
"shadowHidden" INTEGER NOT NULL
);
INSERT INTO sqlb_temp_table_1 SELECT videoID,startTime,endTime,votes,"1",UUID,userID,timeSubmitted,views,category,shadowHidden FROM sponsorTimes;
INSERT INTO sqlb_temp_table_1 SELECT "videoID","startTime","endTime","votes",'1',"UUID","userID","timeSubmitted","views","category","shadowHidden" FROM "sponsorTimes";
DROP TABLE sponsorTimes;
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_1 RENAME TO "sponsorTimes";
/* Add version to config */
INSERT INTO config (key, value) VALUES("version", 1);
INSERT INTO config (key, value) VALUES('version', 1);
COMMIT;

View File

@@ -0,0 +1,30 @@
BEGIN TRANSACTION;
/* Add Hidden field */
CREATE TABLE "sqlb_temp_table_10" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"videoDuration" REAL NOT NULL DEFAULT '0',
"hidden" INTEGER NOT NULL DEFAULT '0',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_10 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category","service","videoDuration",0,"shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_10 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 10 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,8 @@
BEGIN TRANSACTION;
/* Rename table: noSegments to lockCategories */
ALTER TABLE "noSegments" RENAME TO "lockCategories";
UPDATE "config" SET value = 11 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,31 @@
BEGIN TRANSACTION;
/* Add reputation field */
CREATE TABLE "sqlb_temp_table_12" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"videoDuration" REAL NOT NULL DEFAULT '0',
"hidden" INTEGER NOT NULL DEFAULT '0',
"reputation" REAL NOT NULL DEFAULT 0,
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_12 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category","service","videoDuration","hidden",0,"shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_12 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 12 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,17 @@
BEGIN TRANSACTION;
/* Add locked field */
CREATE TABLE "sqlb_temp_table_13" (
"userID" TEXT NOT NULL,
"userName" TEXT NOT NULL,
"locked" INTEGER NOT NULL default '0'
);
INSERT INTO sqlb_temp_table_13 SELECT "userID", "userName", 0 FROM "userNames";
DROP TABLE "userNames";
ALTER TABLE sqlb_temp_table_13 RENAME TO "userNames";
UPDATE "config" SET value = 13 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,9 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "shadowBannedUsers" (
"userID" TEXT NOT NULL
);
UPDATE "config" SET value = 14 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,10 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "unlistedVideos" (
"videoID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL
);
UPDATE "config" SET value = 15 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,15 @@
BEGIN TRANSACTION;
DROP TABLE "unlistedVideos";
CREATE TABLE IF NOT EXISTS "unlistedVideos" (
"videoID" TEXT NOT NULL,
"year" TEXT NOT NULL,
"views" TEXT NOT NULL,
"channelID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL
);
UPDATE "config" SET value = 16 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,19 @@
BEGIN TRANSACTION;
/* Add reason field */
CREATE TABLE "sqlb_temp_table_17" (
"userID" TEXT NOT NULL,
"issueTime" INTEGER NOT NULL,
"issuerUserID" TEXT NOT NULL,
enabled INTEGER NOT NULL,
"reason" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_17 SELECT "userID","issueTime","issuerUserID","enabled", '' FROM "warnings";
DROP TABLE warnings;
ALTER TABLE sqlb_temp_table_17 RENAME TO "warnings";
UPDATE "config" SET value = 17 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,9 @@
BEGIN TRANSACTION;
/* Add hash field */
ALTER TABLE "lockCategories" ADD "hashedVideoID" TEXT NOT NULL default '';
UPDATE "lockCategories" SET "hashedVideoID" = sha256("videoID");
UPDATE "config" SET value = 18 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,32 @@
BEGIN TRANSACTION;
/* Add actionType field */
CREATE TABLE "sqlb_temp_table_19" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"actionType" TEXT NOT NULL DEFAULT 'skip',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"videoDuration" REAL NOT NULL DEFAULT '0',
"hidden" INTEGER NOT NULL DEFAULT '0',
"reputation" REAL NOT NULL DEFAULT 0,
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_19 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category",'skip',"service","videoDuration","hidden","reputation","shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_19 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 19 WHERE key = 'version';
COMMIT;

View File

@@ -8,6 +8,6 @@ CREATE TABLE "noSegments" (
);
/* Add version to config */
UPDATE config SET value = 2 WHERE key = 'version';
UPDATE "config" SET value = 2 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,8 @@
BEGIN TRANSACTION;
/* Add hash field */
ALTER TABLE "lockCategories" ADD "reason" TEXT NOT NULL default '';
UPDATE "config" SET value = 20 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,26 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "archivedSponsorTimes" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL DEFAULT '0',
"incorrectVotes" INTEGER NOT NULL DEFAULT 1,
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'Youtube',
"actionType" TEXT NOT NULL DEFAULT 'skip',
"videoDuration" INTEGER NOT NULL DEFAULT '0',
"hidden" INTEGER NOT NULL DEFAULT '0',
"reputation" REAL NOT NULL DEFAULT '0',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL DEFAULT ''
);
UPDATE "config" SET value = 21 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,10 @@
BEGIN TRANSACTION;
/* Add hash field */
ALTER TABLE "sponsorTimes" ADD "userAgent" TEXT NOT NULL default '';
ALTER TABLE "archivedSponsorTimes" ADD "userAgent" TEXT NOT NULL default '';
UPDATE "config" SET value = 22 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,12 @@
BEGIN TRANSACTION;
DELETE FROM "userNames" WHERE ctid NOT IN ( --!sqlite-ignore
SELECT MIN(ctid) FROM "userNames" --!sqlite-ignore
GROUP BY "userID" --!sqlite-ignore
); --!sqlite-ignore
ALTER TABLE "userNames" ADD UNIQUE("userID"); --!sqlite-ignore
UPDATE "config" SET value = 23 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,21 @@
BEGIN TRANSACTION;
ALTER TABLE "lockCategories" ADD "service" TEXT NOT NULL default 'YouTube';
UPDATE "lockCategories"
SET "service" = "sponsorTimes"."service"
FROM "sponsorTimes"
WHERE "lockCategories"."videoID" = "sponsorTimes"."videoID";
ALTER TABLE "unlistedVideos" ADD "service" TEXT NOT NULL default 'YouTube';
UPDATE "unlistedVideos"
SET "service" = "sponsorTimes"."service"
FROM "sponsorTimes"
WHERE "unlistedVideos"."videoID" = "sponsorTimes"."videoID";
DROP INDEX IF EXISTS "noSegments_videoID";
UPDATE "config" SET value = 24 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,13 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "videoInfo" (
"videoID" TEXT PRIMARY KEY NOT NULL,
"channelID" TEXT NOT NULL,
"title" TEXT NOT NULL,
"published" REAL NOT NULL,
"genreUrl" REAL NOT NULL
);
UPDATE "config" SET value = 25 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,18 @@
BEGIN TRANSACTION;
CREATE TABLE "sqlb_temp_table_26" (
"videoID" TEXT PRIMARY KEY NOT NULL,
"channelID" TEXT NOT NULL,
"title" TEXT NOT NULL,
"published" REAL NOT NULL,
"genreUrl" TEXT NOT NULL
);
INSERT INTO sqlb_temp_table_26 SELECT "videoID", "channelID", "title", "published", '' FROM "videoInfo";
DROP TABLE "videoInfo";
ALTER TABLE sqlb_temp_table_26 RENAME TO "videoInfo";
UPDATE "config" SET value = 26 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,8 @@
BEGIN TRANSACTION;
ALTER TABLE "sponsorTimes" ADD "description" TEXT NOT NULL default '';
ALTER TABLE "archivedSponsorTimes" ADD "description" TEXT NOT NULL default '';
UPDATE "config" SET value = 27 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,13 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "ratings" (
"videoID" TEXT NOT NULL,
"service" TEXT NOT NULL default 'YouTube',
"type" INTEGER NOT NULL,
"count" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL
);
UPDATE "config" SET value = 28 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,21 @@
BEGIN TRANSACTION;
CREATE TABLE "sqlb_temp_table_29" (
"videoID" TEXT NOT NULL,
"userID" TEXT NOT NULL,
"actionType" TEXT NOT NULL DEFAULT 'skip',
"category" TEXT NOT NULL,
"hashedVideoID" TEXT NOT NULL default '',
"reason" TEXT NOT NULL default '',
"service" TEXT NOT NULL default 'YouTube'
);
INSERT INTO sqlb_temp_table_29 SELECT "videoID","userID",'skip',"category","hashedVideoID","reason","service" FROM "lockCategories";
INSERT INTO sqlb_temp_table_29 SELECT "videoID","userID",'mute',"category","hashedVideoID","reason","service" FROM "lockCategories";
DROP TABLE "lockCategories";
ALTER TABLE sqlb_temp_table_29 RENAME TO "lockCategories";
UPDATE "config" SET value = 29 WHERE key = 'version';
COMMIT;

View File

@@ -1,13 +1,11 @@
BEGIN TRANSACTION;
/* hash upgrade test sha256('vid') = '1ff838dc6ca9680d88455341118157d59a055fe6d0e3870f9c002847bebe4663'
/* hash upgrade test sha256('vid') = '1ff838dc6ca9680d88455341118157d59a055fe6d0e3870f9c002847bebe4663' */
/* Add hash field */
ALTER TABLE sponsorTimes ADD hashedVideoID TEXT NOT NULL default "";
UPDATE sponsorTimes SET hashedVideoID = sha256(videoID);
CREATE INDEX IF NOT EXISTS sponsorTimes_hashedVideoID on sponsorTimes(hashedVideoID);
ALTER TABLE "sponsorTimes" ADD "hashedVideoID" TEXT NOT NULL default '';
UPDATE "sponsorTimes" SET "hashedVideoID" = sha256("videoID");
/* Bump version in config */
UPDATE config SET value = 3 WHERE key = "version";
UPDATE "config" SET value = 3 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,7 @@
BEGIN TRANSACTION;
UPDATE "sponsorTimes" SET "actionType" = 'poi' WHERE "category" = 'poi_highlight';
UPDATE "config" SET value = 30 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,25 @@
BEGIN TRANSACTION;
/* START lockCategory migrations
no sponsor migrations
no selfpromo migrations */
/* exclusive_access migrations */
DELETE FROM "lockCategories" WHERE "category" = 'exclusive_access' AND "actionType" != 'full';
/* delete all full locks on categories without full */
DELETE FROM "lockCategories" WHERE "actionType" = 'full' AND "category" in ('interaction', 'intro', 'outro', 'preview', 'filler', 'music_offtopic', 'poi_highlight');
/* delete all non-skip music_offtopic locks */
DELETE FROM "lockCategories" WHERE "category" = 'music_offtopic' AND "actionType" != 'skip';
/* convert all poi_highlight to actionType poi */
UPDATE "lockCategories" SET "actionType" = 'poi' WHERE "category" = 'poi_highlight' AND "actionType" = 'skip';
/* delete all non-skip poi_highlight locks */
DELETE FROM "lockCategories" WHERE "category" = 'poi_highlight' AND "actionType" != 'poi';
/* END lockCategory migrations */
/* delete all redundant userName entries */
DELETE FROM "userNames" WHERE "userName" = "userID" AND "locked" = 0;
UPDATE "config" SET value = 31 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,19 @@
BEGIN TRANSACTION;
-- Add primary keys
ALTER TABLE "sponsorTimes" ADD PRIMARY KEY ("UUID"); --!sqlite-ignore
ALTER TABLE "vipUsers" ADD PRIMARY KEY ("userID"); --!sqlite-ignore
ALTER TABLE "userNames" ADD PRIMARY KEY ("userID"); --!sqlite-ignore
ALTER TABLE "categoryVotes" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "lockCategories" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "warnings" ADD PRIMARY KEY ("userID", "issueTime"); --!sqlite-ignore
ALTER TABLE "shadowBannedUsers" ADD PRIMARY KEY ("userID"); --!sqlite-ignore
ALTER TABLE "unlistedVideos" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
ALTER TABLE "config" ADD PRIMARY KEY ("key"); --!sqlite-ignore
ALTER TABLE "archivedSponsorTimes" ADD PRIMARY KEY ("UUID"); --!sqlite-ignore
ALTER TABLE "ratings" ADD "id" SERIAL PRIMARY KEY; --!sqlite-ignore
UPDATE "config" SET value = 32 WHERE key = 'version';
COMMIT;

View File

@@ -2,11 +2,11 @@ BEGIN TRANSACTION;
/* Create warnings table */
CREATE TABLE "warnings" (
userID TEXT NOT NULL,
issueTime INTEGER NOT NULL,
issuerUserID TEXT NOT NULL
"userID" TEXT NOT NULL,
"issueTime" INTEGER NOT NULL,
"issuerUserID" TEXT NOT NULL
);
UPDATE config SET value = 4 WHERE key = "version";
UPDATE "config" SET value = 4 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,17 @@
BEGIN TRANSACTION;
/* Add enabled field */
CREATE TABLE "sqlb_temp_table_5" (
"userID" TEXT NOT NULL,
"issueTime" INTEGER NOT NULL,
"issuerUserID" TEXT NOT NULL,
enabled INTEGER NOT NULL
);
INSERT INTO sqlb_temp_table_5 SELECT "userID","issueTime","issuerUserID",1 FROM "warnings";
DROP TABLE warnings;
ALTER TABLE sqlb_temp_table_5 RENAME TO "warnings";;
UPDATE "config" SET value = 5 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,27 @@
BEGIN TRANSACTION;
/* Add new voting field */
CREATE TABLE "sqlb_temp_table_6" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_6 SELECT "videoID","startTime","endTime","votes",'0',"incorrectVotes","UUID","userID","timeSubmitted","views","category","shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_6 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 6 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,28 @@
BEGIN TRANSACTION;
/* Add Service field */
CREATE TABLE "sqlb_temp_table_7" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_7 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category",'YouTube', "shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_7 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 7 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,29 @@
BEGIN TRANSACTION;
/* Add Service field */
CREATE TABLE "sqlb_temp_table_8" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"videoDuration" INTEGER NOT NULL DEFAULT '0',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_8 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category","service",'0', "shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_8 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 8 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,29 @@
BEGIN TRANSACTION;
/* Add Service field */
CREATE TABLE "sqlb_temp_table_9" (
"videoID" TEXT NOT NULL,
"startTime" REAL NOT NULL,
"endTime" REAL NOT NULL,
"votes" INTEGER NOT NULL,
"locked" INTEGER NOT NULL default '0',
"incorrectVotes" INTEGER NOT NULL default '1',
"UUID" TEXT NOT NULL UNIQUE,
"userID" TEXT NOT NULL,
"timeSubmitted" INTEGER NOT NULL,
"views" INTEGER NOT NULL,
"category" TEXT NOT NULL DEFAULT 'sponsor',
"service" TEXT NOT NULL DEFAULT 'YouTube',
"videoDuration" REAL NOT NULL DEFAULT '0',
"shadowHidden" INTEGER NOT NULL,
"hashedVideoID" TEXT NOT NULL default ''
);
INSERT INTO sqlb_temp_table_9 SELECT "videoID","startTime","endTime","votes","locked","incorrectVotes","UUID","userID","timeSubmitted","views","category","service",'0', "shadowHidden","hashedVideoID" FROM "sponsorTimes";
DROP TABLE "sponsorTimes";
ALTER TABLE sqlb_temp_table_9 RENAME TO "sponsorTimes";
UPDATE "config" SET value = 9 WHERE key = 'version';
COMMIT;

View File

@@ -0,0 +1,3 @@
POSTGRES_USER=sponsorblock
POSTGRES_PASSWORD=<choose-a-password>
POSTGRES_DB=sponsorTimes

View File

@@ -0,0 +1,13 @@
version: '3'
services:
postgres:
image: postgres:alpine
environment:
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASS}
ports:
- 5432:5432
redis:
image: redis:alpine
ports:
- 6379:6379

41
docker/docker-compose.yml Normal file
View File

@@ -0,0 +1,41 @@
version: '3'
services:
database:
container_name: database
image: postgres:13
env_file:
- database.env
volumes:
- database-data:/var/lib/postgresql/data
ports:
- 5432:5432
restart: always
redis:
container_name: redis
image: redis:6.0
command: /usr/local/etc/redis/redis.conf
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- 32773:6379
restart: always
newleaf:
image: abeltramo/newleaf:latest
container_name: newleaf
restart: always
ports:
- 3241:3000
volumes:
- ./newleaf/configuration.py:/workdir/configuration.py
rsync:
image: mchangrh/rsync:latest
container_name: rsync
restart: always
ports:
- 873:873
volumes:
- ./rsync/rsyncd.conf:/etc/rsyncd.conf
- ./database-export/:/mirror
volumes:
database-data:

View File

@@ -0,0 +1,5 @@
load database
from ./database.db
into postgresql://sponsorblock:pw@127.0.0.1:5432/sponsorTimes
with quote identifiers;

View File

@@ -0,0 +1,17 @@
# ==============================
# You MUST set these settings.
# ==============================
# A URL that this site can be accessed on. Do not include a trailing slash.
website_origin = "http://newleaf:3000"
# ==============================
# These settings are optional.
# ==============================
# The address of the interface to bind to.
#bind_host = "0.0.0.0"
# The port to bind to.
#bind_port = 3000

4
docker/redis/redis.conf Normal file
View File

@@ -0,0 +1,4 @@
maxmemory-policy allkeys-lru
maxmemory 6500mb
appendonly no

15
docker/rsync/rsyncd.conf Normal file
View File

@@ -0,0 +1,15 @@
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
# replace with user accessing the files
[sponsorblock]
use chroot = no
max connections = 10
# path to mirrored files
path = /mirror
comment = sponsorblock-database
read only = true
refuse options = c delete zl
# disallow checksumming and compression level to reduce CPU/IO load
# disallow deleting files clientside

View File

@@ -1,26 +1,12 @@
#!/bin/bash
#!/bin/sh
set -e
echo 'Entrypoint script'
cd /usr/src/app
cp /etc/sponsorblock/config.json . || cat <<EOF > config.json
# blank config, use defaults
cat <<EOF > config.json
{
"port": 8080,
"globalSalt": "[CHANGE THIS]",
"adminUserID": "[CHANGE THIS]",
"youtubeAPIKey": null,
"discordReportChannelWebhookURL": null,
"discordFirstTimeSubmissionsWebhookURL": null,
"discordAutoModWebhookURL": null,
"proxySubmission": null,
"behindProxy": "X-Forwarded-For",
"db": "./databases/sponsorTimes.db",
"privateDB": "./databases/private.db",
"createDatabaseIfNotExist": true,
"schemaFolder": "./databases",
"dbSchema": "./databases/_sponsorTimes.db.sql",
"privateDBSchema": "./databases/_private.db.sql",
"mode": "development",
"readOnly": false
}
EOF
node index.js
node dist/src/index.js

View File

@@ -1,6 +0,0 @@
var config = require('./src/config.js');
var createServer = require('./src/app.js');
const logger = require('./src/utils/logger.js');
var server = createServer(() => {
logger.info("Server started on port " + config.port + ".");
});

11
nginx/cors.conf Normal file
View File

@@ -0,0 +1,11 @@
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
# cache CORS for 24 hours
add_header 'Access-Control-Max-Age' 86400;
# return empty response for preflight
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

7
nginx/error.conf Normal file
View File

@@ -0,0 +1,7 @@
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /error.html;
location = /error.html {
ssi on;
internal;
root /etc/nginx/error;
}

1
nginx/error/error.html Normal file
View File

@@ -0,0 +1 @@
<!--# echo var="status"--> <!--# echo var="status_text"--> https://status.sponsor.ajay.app

15
nginx/error_map.conf Normal file
View File

@@ -0,0 +1,15 @@
map $status $status_text {
400 'Bad Request';
401 'Unauthorized';
403 'Forbidden';
404 'Not Found';
405 'Method Not Allowed';
408 'Request Timeout';
409 'Conflict';
429 'Too Many Requests';
500 'Internal Server Error';
502 'Bad Gateway';
503 'Service Unavailable';
504 'Gateway Timeout';
505 'HTTP Version Not Supported';
}

317
nginx/nginx.conf Normal file
View File

@@ -0,0 +1,317 @@
worker_processes 2;
worker_rlimit_nofile 500000;
worker_shutdown_timeout 10;
events {
worker_connections 100000; # Default: 1024
#use epoll;
#multi_accept on;
}
http {
log_format no_ip '$remote_user [$time_local] '
'"$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"';
#limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req_log_level warn;
include /etc/nginx/mime.types;
include /etc/nginx/proxy.conf;
# error_map has to be at http level
include /etc/nginx/error_map.conf;
# Custom MIME definition
types {
text/csv csv;
}
# keepalive settings
#keepalive_requests 10;
keepalive_timeout 10s;
http2_idle_timeout 20s; # replaced by keepalive_timeout in 1.19.7
access_log off;
#error_log /etc/nginx/logs/error.log warn;
error_log /dev/null crit;
upstream backend_GET {
least_conn;
#keepalive 5;
#server localhost:4441;
#server localhost:4442;
#server localhost:4443;
#server localhost:4444;
#server localhost:4445;
#server localhost:4446;
#server localhost:4447;
#server localhost:4448;
#server 10.0.0.4:4441 max_fails=25 fail_timeout=20s;
#server 10.0.0.3:4441 max_fails=25 fail_timeout=20s;
#server 10.0.0.3:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.5:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.5:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.6:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.6:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.9:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.9:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.12:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.12:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.10:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.10:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.13:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.13:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.14:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.14:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.11:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.11:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.16:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.16:4442 max_fails=25 fail_timeout=20s;
server 10.0.0.17:4441 max_fails=25 fail_timeout=20s;
server 10.0.0.17:4442 max_fails=25 fail_timeout=20s;
#server 134.209.69.251:80 backup;
#server 116.203.32.253:80 backup;
#server 116.203.32.253:80;
}
upstream backend_POST {
#server localhost:4441;
#server localhost:4442;
server 10.0.0.3:4441 max_fails=25 fail_timeout=15s;
server 10.0.0.4:4441 max_fails=25 fail_timeout=15s;
#server 10.0.0.3:4442;
}
upstream backend_db {
server 10.0.0.4:4441 max_fails=1 fail_timeout=3s;
#server 10.0.0.3:4441;
#server 10.0.0.4;
}
upstream backend_db_dl {
server 10.0.0.4;
}
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;
include /etc/nginx/error.conf;
set_real_ip_from 10.0.0.0/24;
real_ip_header proxy_protocol;
location /news {
return 301 https://blog.ajay.app/sponsorblock;
}
location /viewer {
return 301 https://sb.ltn.fi;
}
location /test/ {
# return 404 "";
proxy_pass http://10.0.0.4:4445/;
#proxy_pass https://sbtest.etcinit.com/;
}
#access_log /etc/nginx/logs/requests.log no_ip buffer=64k;
location /api/skipSegments {
include /etc/nginx/cors.conf;
#return 200 "[]";
proxy_pass http://backend_$request_method;
#proxy_cache CACHEZONE;
#proxy_cache_valid 10s;
#limit_req zone=mylimit;
#access_log /etc/nginx/logs/download.log no_ip;
gzip on;
if ($request_method = POST) {
access_log /etc/nginx/logs/submissions.log user_agent buffer=64k;
}
#proxy_read_timeout 6s;
#proxy_next_upstream error timeout http_500 http_502;
}
location /api/getTopUsers {
include /etc/nginx/cors.conf;
proxy_pass http://backend_GET;
proxy_cache CACHEZONE;
proxy_cache_valid 20m;
}
location /api/getTotalStats {
include /etc/nginx/cors.conf;
proxy_pass http://backend_POST;
proxy_cache CACHEZONE;
proxy_cache_valid 20m;
#return 204;
}
location /api/getTopCategoryUsers {
include /etc/nginx/cors.conf;
proxy_pass http://backend_POST;
proxy_cache CACHEZONE;
proxy_cache_valid 20m;
}
location /api/getVideoSponsorTimes {
include /etc/nginx/cors.conf;
proxy_pass http://backend_GET;
}
location /api/isUserVIP {
include /etc/nginx/cors.conf;
proxy_pass http://backend_GET;
}
location /download/ {
#access_log /etc/nginx/logs/download.log no_ip buffer=64k;
gzip on;
proxy_max_temp_file_size 0;
#proxy_cache CACHEZONE;
#proxy_cache_valid 20m;
#proxy_http_version 1.0;
#gzip_types text/csv;
#gzip_comp_level 1;
#proxy_buffering off;
proxy_pass http://backend_db;
#alias /home/sbadmin/sponsor/docker/database-export/;
#return 307 https://rsync.sponsor.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 {
include /etc/nginx/cors.conf;
proxy_pass http://backend_POST;
}
location / {
root /home/sbadmin/SponsorBlockSite/public-prod;
error_page 404 /404.html;
}
listen [::]:443 default_server ssl http2 ipv6only=on backlog=323999;
listen 443 default_server ssl http2 reuseport backlog=3000999; # managed by Certbot
listen 4443 default_server ssl http2 proxy_protocol reuseport backlog=3000999;
#listen 443 http3 reuseport;
#ssl_protocols TLSv1.2 TLSv1.3;
listen 8081 proxy_protocol;
port_in_redirect off;
ssl_certificate /home/sbadmin/certs/cert.pem;
ssl_certificate_key /home/sbadmin/certs/key.pem;
#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 {
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 / {
root /home/sbadmin/SponsorBlockSite/public-prod;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /home/sbadmin/certs/cert.pem;
ssl_certificate_key /home/sbadmin/certs/key.pem;
#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;
return 301 https://$host$request_uri;
listen [::]:80 ipv6only=on;
listen 8080 proxy_protocol;
listen 80;
server_name sponsor.ajay.app api.sponsor.ajay.app, cdnsponsor.ajay.app, wiki.sponsor.ajay.app;
return 404; # managed by Certbot
}
server {
server_name wiki.sponsor.ajay.app; # managed by Certbot
location /.well-known/ {
root /home/sbadmin/SponsorBlockSite/public-prod;
}
location ~* ^/index.php/(?<pagename>.*)$ {
return 301 /w/$pagename;
}
location / {
proxy_pass http://10.0.0.3:8080;
}
port_in_redirect off;
listen [::]:443 ssl http2;
listen 443 ssl http2; # managed by Certbot
listen 8081 proxy_protocol;
#listen 443 http3 reuseport;
#ssl_protocols TLSv1.2 TLSv1.3;
#listen 80;
ssl_certificate /home/sbadmin/certs/cert.pem;
ssl_certificate_key /home/sbadmin/certs/key.pem;
#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
}
}

12
nginx/proxy.conf Normal file
View File

@@ -0,0 +1,12 @@
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 5s;
#proxy_send_timeout 10;
proxy_read_timeout 30s;
proxy_buffers 32 4k;
proxy_http_version 1.1;

5
nodemon.json Normal file
View File

@@ -0,0 +1,5 @@
{
"watch": ["src"],
"ext": "ts,json",
"exec": "(npm test || echo test failed) && npm start"
}

9351
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,29 +2,52 @@
"name": "sponsor_block_server",
"version": "0.1.0",
"description": "Server that holds the SponsorBlock database",
"main": "index.js",
"main": "src/index.ts",
"scripts": {
"test": "node test.js",
"dev": "nodemon -x \"(npm test || echo test failed) && npm start\"",
"test": "npm run tsc && ts-node test/test.ts",
"dev": "nodemon",
"dev:bash": "nodemon -x 'npm test ; npm start'",
"start": "node index.js"
"postgres:docker": "docker run --rm -p 5432:5432 -e POSTGRES_USER=ci_db_user -e POSTGRES_PASSWORD=ci_db_pass postgres:alpine",
"redis:docker": "docker run --rm -p 6379:6379 redis:alpine",
"start": "ts-node src/index.ts",
"tsc": "tsc -p tsconfig.json",
"lint": "eslint src test",
"lint:fix": "eslint src test --fix"
},
"author": "Ajay Ramachandran",
"license": "MIT",
"dependencies": {
"better-sqlite3": "^5.4.3",
"axios": "^0.24.0",
"better-sqlite3": "^7.4.5",
"cron": "^1.8.2",
"express": "^4.17.1",
"express-rate-limit": "^5.1.3",
"http": "0.0.0",
"iso8601-duration": "^1.2.0",
"node-fetch": "^2.6.0",
"redis": "^3.0.2",
"sync-mysql": "^3.0.1",
"uuid": "^3.3.2",
"youtube-api": "^2.0.10"
"express-promise-router": "^4.1.1",
"express-rate-limit": "^6.3.0",
"lodash": "^4.17.21",
"pg": "^8.7.1",
"rate-limit-redis": "^3.0.1",
"redis": "^4.0.6",
"sync-mysql": "^3.0.1"
},
"devDependencies": {
"mocha": "^7.1.1",
"nodemon": "^2.0.2"
"@types/better-sqlite3": "^7.4.1",
"@types/cron": "^1.7.3",
"@types/express": "^4.17.13",
"@types/lodash": "^4.14.178",
"@types/mocha": "^9.0.0",
"@types/node": "^16.11.11",
"@types/pg": "^8.6.1",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"eslint": "^8.3.0",
"mocha": "^9.1.3",
"nodemon": "^2.0.15",
"sinon": "^12.0.1",
"ts-mock-imports": "^1.3.8",
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
},
"engines": {
"node": ">=10"
}
}

View File

@@ -1,137 +0,0 @@
var express = require('express');
// Create a service (the app object is just a callback).
var app = express();
var config = require('./config.js');
var redis = require('./utils/redis.js');
const getIP = require('./utils/getIP.js');
const getHash = require('./utils/getHash.js');
// Middleware
const rateLimitMiddleware = require('./middleware/requestRateLimit.js');
var corsMiddleware = require('./middleware/cors.js');
var loggerMiddleware = require('./middleware/logger.js');
const userCounter = require('./middleware/userCounter.js');
// Routes
var getSkipSegments = require('./routes/getSkipSegments.js').endpoint;
var postSkipSegments = require('./routes/postSkipSegments.js');
var getSkipSegmentsByHash = require('./routes/getSkipSegmentsByHash.js');
var voteOnSponsorTime = require('./routes/voteOnSponsorTime.js');
var viewedVideoSponsorTime = require('./routes/viewedVideoSponsorTime.js');
var setUsername = require('./routes/setUsername.js');
var getUsername = require('./routes/getUsername.js');
var shadowBanUser = require('./routes/shadowBanUser.js');
var addUserAsVIP = require('./routes/addUserAsVIP.js');
var getSavedTimeForUser = require('./routes/getSavedTimeForUser.js');
var getViewsForUser = require('./routes/getViewsForUser.js');
var getTopUsers = require('./routes/getTopUsers.js');
var getTotalStats = require('./routes/getTotalStats.js');
var getDaysSavedFormatted = require('./routes/getDaysSavedFormatted.js');
var getUserInfo = require('./routes/getUserInfo.js');
var postNoSegments = require('./routes/postNoSegments.js');
var deleteNoSegments = require('./routes/deleteNoSegments.js');
var getIsUserVIP = require('./routes/getIsUserVIP.js');
var warnUser = require('./routes/postWarning.js');
var postSegmentShift = require('./routes/postSegmentShift.js');
// Old Routes
var oldGetVideoSponsorTimes = require('./routes/oldGetVideoSponsorTimes.js');
var oldSubmitSponsorTimes = require('./routes/oldSubmitSponsorTimes.js');
// Rate limit endpoint lists
let voteEndpoints = [voteOnSponsorTime.endpoint];
let viewEndpoints = [viewedVideoSponsorTime];
if (config.rateLimit) {
if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote));
if (config.rateLimit.view) viewEndpoints.unshift(rateLimitMiddleware(config.rateLimit.view));
}
//setup CORS correctly
app.use(corsMiddleware);
app.use(loggerMiddleware);
app.use(express.json())
if (config.userCounterURL) app.use(userCounter);
// Setup pretty JSON
if (config.mode === "development") app.set('json spaces', 2);
// Set production mode
app.set('env', config.mode || 'production');
//add the get function
app.get('/api/getVideoSponsorTimes', oldGetVideoSponsorTimes);
//add the oldpost function
app.get('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
app.post('/api/postVideoSponsorTimes', oldSubmitSponsorTimes);
//add the skip segments functions
app.get('/api/skipSegments', getSkipSegments);
app.post('/api/skipSegments', postSkipSegments);
// add the privacy protecting skip segments functions
app.get('/api/skipSegments/:prefix', getSkipSegmentsByHash);
//voting endpoint
app.get('/api/voteOnSponsorTime', ...voteEndpoints);
app.post('/api/voteOnSponsorTime', ...voteEndpoints);
//Endpoint when a submission is skipped
app.get('/api/viewedVideoSponsorTime', ...viewEndpoints);
app.post('/api/viewedVideoSponsorTime', ...viewEndpoints);
//To set your username for the stats view
app.post('/api/setUsername', setUsername);
//get what username this user has
app.get('/api/getUsername', getUsername);
//Endpoint used to hide a certain user's data
app.post('/api/shadowBanUser', shadowBanUser);
//Endpoint used to make a user a VIP user with special privileges
app.post('/api/addUserAsVIP', addUserAsVIP);
//Gets all the views added up for one userID
//Useful to see how much one user has contributed
app.get('/api/getViewsForUser', getViewsForUser);
//Gets all the saved time added up (views * sponsor length) for one userID
//Useful to see how much one user has contributed
//In minutes
app.get('/api/getSavedTimeForUser', getSavedTimeForUser);
app.get('/api/getTopUsers', getTopUsers);
//send out totals
//send the total submissions, total views and total minutes saved
app.get('/api/getTotalStats', getTotalStats);
app.get('/api/getUserInfo', getUserInfo);
//send out a formatted time saved total
app.get('/api/getDaysSavedFormatted', getDaysSavedFormatted);
//submit video containing no segments
app.post('/api/noSegments', postNoSegments);
app.delete('/api/noSegments', deleteNoSegments);
//get if user is a vip
app.get('/api/isUserVIP', getIsUserVIP);
//sent user a warning
app.post('/api/warnUser', warnUser);
//get if user is a vip
app.post('/api/segmentShift', postSegmentShift);
app.get('/database.db', function (req, res) {
res.sendFile("./databases/sponsorTimes.db", { root: "./" });
});
// Create an HTTP service.
module.exports = function createServer (callback) {
return app.listen(config.port, callback);
}

215
src/app.ts Normal file
View File

@@ -0,0 +1,215 @@
import express, { Request, RequestHandler, Response, Router } from "express";
import { config } from "./config";
import { oldSubmitSponsorTimes } from "./routes/oldSubmitSponsorTimes";
import { oldGetVideoSponsorTimes } from "./routes/oldGetVideoSponsorTimes";
import { postSegmentShift } from "./routes/postSegmentShift";
import { postWarning } from "./routes/postWarning";
import { getIsUserVIP } from "./routes/getIsUserVIP";
import { deleteLockCategoriesEndpoint } from "./routes/deleteLockCategories";
import { postLockCategories } from "./routes/postLockCategories";
import { endpoint as getUserInfo } from "./routes/getUserInfo";
import { getDaysSavedFormatted } from "./routes/getDaysSavedFormatted";
import { getTotalStats } from "./routes/getTotalStats";
import { getTopUsers } from "./routes/getTopUsers";
import { getViewsForUser } from "./routes/getViewsForUser";
import { getSavedTimeForUser } from "./routes/getSavedTimeForUser";
import { addUserAsVIP } from "./routes/addUserAsVIP";
import { shadowBanUser } from "./routes/shadowBanUser";
import { getUsername } from "./routes/getUsername";
import { setUsername } from "./routes/setUsername";
import { viewedVideoSponsorTime } from "./routes/viewedVideoSponsorTime";
import { voteOnSponsorTime, getUserID as voteGetUserID } from "./routes/voteOnSponsorTime";
import { getSkipSegmentsByHash } from "./routes/getSkipSegmentsByHash";
import { postSkipSegments } from "./routes/postSkipSegments";
import { endpoint as getSkipSegments } from "./routes/getSkipSegments";
import { userCounter } from "./middleware/userCounter";
import { loggerMiddleware } from "./middleware/logger";
import { corsMiddleware } from "./middleware/cors";
import { apiCspMiddleware } from "./middleware/apiCsp";
import { rateLimitMiddleware } from "./middleware/requestRateLimit";
import dumpDatabase, { appExportPath, downloadFile } from "./routes/dumpDatabase";
import { endpoint as getSegmentInfo } from "./routes/getSegmentInfo";
import { postClearCache } from "./routes/postClearCache";
import { addUnlistedVideo } from "./routes/addUnlistedVideo";
import { postPurgeAllSegments } from "./routes/postPurgeAllSegments";
import { getUserID } from "./routes/getUserID";
import { getLockCategories } from "./routes/getLockCategories";
import { getLockCategoriesByHash } from "./routes/getLockCategoriesByHash";
import { endpoint as getSearchSegments } from "./routes/getSearchSegments";
import { getStatus } from "./routes/getStatus";
import { getLockReason } from "./routes/getLockReason";
import { getUserStats } from "./routes/getUserStats";
import ExpressPromiseRouter from "express-promise-router";
import { Server } from "http";
import { youtubeApiProxy } from "./routes/youtubeApiProxy";
import { getChapterNames } from "./routes/getChapterNames";
import { postRating } from "./routes/ratings/postRating";
import { getRating } from "./routes/ratings/getRating";
import { postClearCache as ratingPostClearCache } from "./routes/ratings/postClearCache";
import { getTopCategoryUsers } from "./routes/getTopCategoryUsers";
import { addUserAsTempVIP } from "./routes/addUserAsTempVIP";
export function createServer(callback: () => void): Server {
// Create a service (the app object is just a callback).
const app = express();
const router = ExpressPromiseRouter();
app.use(router);
//setup CORS correctly
router.use(corsMiddleware);
router.use(loggerMiddleware);
router.use("/api/", apiCspMiddleware);
router.use(express.json());
if (config.userCounterURL) router.use(userCounter);
// Setup pretty JSON
if (config.mode === "development") app.set("json spaces", 2);
// Set production mode
app.set("env", config.mode || "production");
setupRoutes(router);
return app.listen(config.port, callback);
}
function setupRoutes(router: Router) {
// Rate limit endpoint lists
const voteEndpoints: RequestHandler[] = [voteOnSponsorTime];
const viewEndpoints: RequestHandler[] = [viewedVideoSponsorTime];
const postRateEndpoints: RequestHandler[] = [postRating];
if (config.rateLimit) {
if (config.rateLimit.vote) voteEndpoints.unshift(rateLimitMiddleware(config.rateLimit.vote, voteGetUserID));
if (config.rateLimit.view) viewEndpoints.unshift(rateLimitMiddleware(config.rateLimit.view));
if (config.rateLimit.rate) postRateEndpoints.unshift(rateLimitMiddleware(config.rateLimit.rate));
}
//add the get function
router.get("/api/getVideoSponsorTimes", oldGetVideoSponsorTimes);
//add the oldpost function
router.get("/api/postVideoSponsorTimes", oldSubmitSponsorTimes);
router.post("/api/postVideoSponsorTimes", oldSubmitSponsorTimes);
//add the skip segments functions
router.get("/api/skipSegments", getSkipSegments);
router.post("/api/skipSegments", postSkipSegments);
// add the privacy protecting skip segments functions
router.get("/api/skipSegments/:prefix", getSkipSegmentsByHash);
//voting endpoint
router.get("/api/voteOnSponsorTime", ...voteEndpoints);
router.post("/api/voteOnSponsorTime", ...voteEndpoints);
//Endpoint when a submission is skipped
router.get("/api/viewedVideoSponsorTime", ...viewEndpoints);
router.post("/api/viewedVideoSponsorTime", ...viewEndpoints);
//To set your username for the stats view
router.post("/api/setUsername", setUsername);
//get what username this user has
router.get("/api/getUsername", getUsername);
//Endpoint used to hide a certain user's data
router.post("/api/shadowBanUser", shadowBanUser);
//Endpoint used to make a user a VIP user with special privileges
router.post("/api/addUserAsVIP", addUserAsVIP);
//Endpoint to add a user as a temporary VIP
router.post("/api/addUserAsTempVIP", addUserAsTempVIP);
//Gets all the views added up for one userID
//Useful to see how much one user has contributed
router.get("/api/getViewsForUser", getViewsForUser);
//Gets all the saved time added up (views * sponsor length) for one userID
//Useful to see how much one user has contributed
//In minutes
router.get("/api/getSavedTimeForUser", getSavedTimeForUser);
router.get("/api/getTopUsers", getTopUsers);
router.get("/api/getTopCategoryUsers", getTopCategoryUsers);
//send out totals
//send the total submissions, total views and total minutes saved
router.get("/api/getTotalStats", getTotalStats);
router.get("/api/getUserInfo", getUserInfo);
router.get("/api/userInfo", getUserInfo);
//send out a formatted time saved total
router.get("/api/getDaysSavedFormatted", getDaysSavedFormatted);
//submit video to lock categories
router.post("/api/noSegments", postLockCategories);
router.post("/api/lockCategories", postLockCategories);
router.delete("/api/noSegments", deleteLockCategoriesEndpoint);
router.delete("/api/lockCategories", deleteLockCategoriesEndpoint);
//get if user is a vip
router.get("/api/isUserVIP", getIsUserVIP);
//sent user a warning
router.post("/api/warnUser", postWarning);
//get if user is a vip
router.post("/api/segmentShift", postSegmentShift);
//get segment info
router.get("/api/segmentInfo", getSegmentInfo);
//clear cache as VIP
router.post("/api/clearCache", postClearCache);
//purge all segments for VIP
router.post("/api/purgeAllSegments", postPurgeAllSegments);
router.post("/api/unlistedVideo", addUnlistedVideo);
// get userID from username
router.get("/api/userID", getUserID);
// get lock categores from userID
router.get("/api/lockCategories", getLockCategories);
// get privacy protecting lock categories functions
router.get("/api/lockCategories/:prefix", getLockCategoriesByHash);
// get all segments that match a search
router.get("/api/searchSegments", getSearchSegments);
// autocomplete chapter names
router.get("/api/chapterNames", getChapterNames);
// get status
router.get("/api/status/:value", getStatus);
router.get("/api/status", getStatus);
router.get("/api/youtubeApiProxy", youtubeApiProxy);
// get user category stats
router.get("/api/userStats", getUserStats);
router.get("/api/lockReason", getLockReason);
// ratings
router.get("/api/ratings/rate/:prefix", getRating);
router.get("/api/ratings/rate", getRating);
router.post("/api/ratings/rate", postRateEndpoints);
router.post("/api/ratings/clearCache", ratingPostClearCache);
if (config.postgres?.enabled) {
router.get("/database", (req, res) => dumpDatabase(req, res, true));
router.get("/database.json", (req, res) => dumpDatabase(req, res, false));
router.get("/database/*", downloadFile);
router.use("/download", express.static(appExportPath));
} else {
router.get("/database.db", function (req: Request, res: Response) {
res.sendFile("./databases/sponsorTimes.db", { root: "./" });
});
}
}

View File

@@ -1,37 +0,0 @@
const fs = require('fs');
let config = {};
// Check to see if launched in test mode
if (process.env.npm_lifecycle_script === 'node test.js') {
config = JSON.parse(fs.readFileSync('test.json'));
} else {
config = JSON.parse(fs.readFileSync('config.json'));
}
addDefaults(config, {
"port": 80,
"behindProxy": "X-Forwarded-For",
"db": "./databases/sponsorTimes.db",
"privateDB": "./databases/private.db",
"createDatabaseIfNotExist": true,
"schemaFolder": "./databases",
"dbSchema": "./databases/_sponsorTimes.db.sql",
"privateDBSchema": "./databases/_private.db.sql",
"readOnly": false,
"webhooks": [],
"categoryList": ["sponsor", "intro", "outro", "interaction", "selfpromo", "music_offtopic"],
"maxNumberOfActiveWarnings": 3,
"hoursAfterWarningExpires": 24
})
module.exports = config;
// Add defaults
function addDefaults(config, defaults) {
for (const key in defaults) {
if(!config.hasOwnProperty(key)) {
config[key] = defaults[key];
}
}
};

185
src/config.ts Normal file
View File

@@ -0,0 +1,185 @@
import fs from "fs";
import { SBSConfig } from "./types/config.model";
import packageJson from "../package.json";
import { isBoolean, isNumber } from "lodash";
const isTestMode = process.env.npm_lifecycle_script === packageJson.scripts.test;
const configFile = process.env.TEST_POSTGRES ? "ci.json"
: isTestMode ? "test.json"
: "config.json";
export const config: SBSConfig = JSON.parse(fs.readFileSync(configFile).toString("utf8"));
addDefaults(config, {
port: 8080,
behindProxy: "X-Forwarded-For",
db: "./databases/sponsorTimes.db",
privateDB: "./databases/private.db",
createDatabaseIfNotExist: true,
schemaFolder: "./databases",
dbSchema: "./databases/_sponsorTimes.db.sql",
privateDBSchema: "./databases/_private.db.sql",
readOnly: false,
webhooks: [],
categoryList: ["sponsor", "selfpromo", "exclusive_access", "interaction", "intro", "outro", "preview", "music_offtopic", "filler", "poi_highlight"],
categorySupport: {
sponsor: ["skip", "mute", "full"],
selfpromo: ["skip", "mute", "full"],
exclusive_access: ["full"],
interaction: ["skip", "mute"],
intro: ["skip", "mute"],
outro: ["skip", "mute"],
preview: ["skip", "mute"],
filler: ["skip", "mute"],
music_offtopic: ["skip"],
poi_highlight: ["poi"],
chapter: ["chapter"]
},
maxNumberOfActiveWarnings: 1,
hoursAfterWarningExpires: 16300000,
adminUserID: "",
discordCompletelyIncorrectReportWebhookURL: null,
discordFirstTimeSubmissionsWebhookURL: null,
discordNeuralBlockRejectWebhookURL: null,
discordFailedReportChannelWebhookURL: null,
discordReportChannelWebhookURL: null,
getTopUsersCacheTimeMinutes: 240,
globalSalt: null,
mode: "",
neuralBlockURL: null,
proxySubmission: null,
rateLimit: {
vote: {
windowMs: 900000,
max: 15,
message: "OK",
statusCode: 200,
},
view: {
windowMs: 900000,
max: 10,
statusCode: 200,
message: "OK",
},
rate: {
windowMs: 900000,
max: 20,
statusCode: 200,
message: "Success",
}
},
userCounterURL: null,
newLeafURLs: null,
maxRewardTimePerSegmentInSeconds: 600,
poiMinimumStartTime: 2,
postgres: {
enabled: false,
user: "",
host: "",
password: "",
port: 5432,
max: 150,
min: 10
},
dumpDatabase: {
enabled: false,
minTimeBetweenMs: 180000,
appExportPath: "./docker/database-export",
tables: [{
name: "sponsorTimes",
order: "timeSubmitted"
},
{
name: "userNames"
},
{
name: "categoryVotes"
},
{
name: "lockCategories",
},
{
name: "warnings",
order: "issueTime"
},
{
name: "vipUsers"
},
{
name: "unlistedVideos"
},
{
name: "videoInfo"
},
{
name: "ratings"
}]
},
diskCacheURL: null,
crons: null,
redis: {
enabled: false,
socket: {
host: "",
port: 0
},
disableOfflineQueue: true
}
});
loadFromEnv(config);
migrate(config);
// Add defaults
function addDefaults(config: SBSConfig, defaults: SBSConfig) {
for (const key in defaults) {
if (!Object.prototype.hasOwnProperty.call(config, key)) {
config[key] = defaults[key];
}
}
}
function migrate(config: SBSConfig) {
// Redis change
if (config.redis) {
const redisConfig = config.redis as any;
if (redisConfig.host || redisConfig.port) {
config.redis.socket = {
host: redisConfig.host,
port: redisConfig.port
};
}
if (redisConfig.enable_offline_queue !== undefined) {
config.disableOfflineQueue = !redisConfig.enable_offline_queue;
}
if (redisConfig.socket?.host && redisConfig.enabled === undefined) {
redisConfig.enabled = true;
}
}
if (config.postgres && config.postgres.user && config.postgres.enabled === undefined) {
config.postgres.enabled = true;
}
}
function loadFromEnv(config: SBSConfig, prefix = "") {
for (const key in config) {
const fullKey = (prefix ? `${prefix}_` : "") + key;
const data = config[key];
if (data && typeof data === "object" && !Array.isArray(data)) {
loadFromEnv(data, fullKey);
} else if (process.env[fullKey]) {
const value = process.env[fullKey];
if (isNumber(value)) {
config[key] = parseInt(value, 10);
} else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
config[key] = value === "true";
} else if (key === "newLeafURLs") {
config[key] = [value];
} else {
config[key] = value;
}
}
}
}

View File

@@ -0,0 +1,67 @@
import { CronJob } from "cron";
import { config as serverConfig } from "../config";
import { Logger } from "../utils/logger";
import { db } from "../databases/databases";
import { DBSegment } from "../types/segments.model";
const jobConfig = serverConfig?.crons?.downvoteSegmentArchive;
export const archiveDownvoteSegment = async (dayLimit: number, voteLimit: number, runTime?: number): Promise<number> => {
const timeNow = runTime || new Date().getTime();
const threshold = dayLimit * 86400000;
Logger.info(`DownvoteSegmentArchiveJob starts at ${timeNow}`);
try {
// insert into archive sponsorTime
await db.prepare(
"run",
`INSERT INTO "archivedSponsorTimes"
SELECT *
FROM "sponsorTimes"
WHERE "votes" < ? AND (? - "timeSubmitted") > ?`,
[
voteLimit,
timeNow,
threshold
]
) as DBSegment[];
} catch (err) {
Logger.error("Execption when insert segment in archivedSponsorTimes");
Logger.error(err as string);
return 1;
}
// remove from sponsorTime
try {
await db.prepare(
"run",
'DELETE FROM "sponsorTimes" WHERE "votes" < ? AND (? - "timeSubmitted") > ?',
[
voteLimit,
timeNow,
threshold
]
) as DBSegment[];
} catch (err) {
Logger.error("Execption when deleting segment in sponsorTimes");
Logger.error(err as string);
return 1;
}
Logger.info("DownvoteSegmentArchiveJob finished");
return 0;
};
const DownvoteSegmentArchiveJob = new CronJob(
jobConfig?.schedule || "0 0 * * * 0",
() => archiveDownvoteSegment(jobConfig?.timeThresholdInDays, jobConfig?.voteThreshold)
);
if (serverConfig?.crons?.enabled && jobConfig && !jobConfig.schedule) {
Logger.error("Invalid cron schedule for downvoteSegmentArchive");
}
export default DownvoteSegmentArchiveJob;

13
src/cronjob/index.ts Normal file
View File

@@ -0,0 +1,13 @@
import { Logger } from "../utils/logger";
import { config } from "../config";
import DownvoteSegmentArchiveJob from "./downvoteSegmentArchiveJob";
export function startAllCrons (): void {
if (config?.crons?.enabled) {
Logger.info("Crons started");
DownvoteSegmentArchiveJob.start();
} else {
Logger.info("Crons dissabled");
}
}

View File

@@ -0,0 +1,7 @@
export interface IDatabase {
init(): Promise<void>;
prepare(type: QueryType, query: string, params?: any[]): Promise<any | any[] | void>;
}
export type QueryType = "get" | "all" | "run";

View File

@@ -1,28 +0,0 @@
var MysqlInterface = require('sync-mysql');
const logger = require('../utils/logger.js');
class Mysql {
constructor(msConfig) {
this.connection = new MysqlInterface(msConfig);
}
exec(query) {
this.prepare('run', query, []);
}
prepare (type, query, params) {
logger.debug("prepare (mysql): type: " + type + ", query: " + query + ", params: " + params);
if (type === 'get') {
return this.connection.query(query, params)[0];
} else if (type === 'run') {
this.connection.query(query, params);
} else if (type === 'all') {
return this.connection.query(query, params);
} else {
logger.warn('returning undefined...');
return undefined;
}
}
}
module.exports = Mysql;

35
src/databases/Mysql.ts Normal file
View File

@@ -0,0 +1,35 @@
import { Logger } from "../utils/logger";
import { IDatabase, QueryType } from "./IDatabase";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import MysqlInterface from "sync-mysql";
export class Mysql implements IDatabase {
private connection: any;
constructor(private config: unknown) {
}
// eslint-disable-next-line require-await
async init(): Promise<void> {
this.connection = new MysqlInterface(this.config);
}
prepare(type: QueryType, query: string, params?: any[]): Promise<any[]> {
Logger.debug(`prepare (mysql): type: ${type}, query: ${query}, params: ${params}`);
const queryResult = this.connection.query(query, params);
switch (type) {
case "get": {
return queryResult[0];
}
case "all": {
return queryResult;
}
case "run": {
break;
}
}
}
}

137
src/databases/Postgres.ts Normal file
View File

@@ -0,0 +1,137 @@
import { Logger } from "../utils/logger";
import { IDatabase, QueryType } from "./IDatabase";
import { Client, Pool, PoolClient, types } from "pg";
import fs from "fs";
// return numeric (pg_type oid=1700) as float
types.setTypeParser(1700, function(val) {
return parseFloat(val);
});
// return int8 (pg_type oid=20) as int
types.setTypeParser(20, function(val) {
return parseInt(val, 10);
});
export class Postgres implements IDatabase {
private pool: Pool;
constructor(private config: Record<string, any>) {}
async init(): Promise<void> {
this.pool = new Pool(this.config.postgres);
if (!this.config.readOnly) {
if (this.config.createDbIfNotExists) {
await this.createDB();
}
if (this.config.createDbIfNotExists && !this.config.readOnly && fs.existsSync(this.config.dbSchemaFileName)) {
await this.pool.query(this.processUpgradeQuery(fs.readFileSync(this.config.dbSchemaFileName).toString()));
}
// Upgrade database if required
await this.upgradeDB(this.config.fileNamePrefix, this.config.dbSchemaFolder);
try {
await this.applyIndexes(this.config.fileNamePrefix, this.config.dbSchemaFolder);
} catch (e) {
Logger.warn("Applying indexes failed. See https://github.com/ajayyy/SponsorBlockServer/wiki/Postgres-Extensions for more information.");
Logger.warn(e as string);
}
}
}
async prepare(type: QueryType, query: string, params?: any[]): Promise<any[]> {
// Convert query to use numbered parameters
let count = 1;
for (let char = 0; char < query.length; char++) {
if (query.charAt(char) === "?") {
query = `${query.slice(0, char)}$${count}${query.slice(char + 1)}`;
count++;
}
}
Logger.debug(`prepare (postgres): type: ${type}, query: ${query}, params: ${params}`);
let client: PoolClient;
try {
client = await this.pool.connect();
const queryResult = await client.query({ text: query, values: params });
switch (type) {
case "get": {
const value = queryResult.rows[0];
Logger.debug(`result (postgres): ${JSON.stringify(value)}`);
return value;
}
case "all": {
const values = queryResult.rows;
Logger.debug(`result (postgres): ${JSON.stringify(values)}`);
return values;
}
case "run": {
break;
}
}
} catch (err) {
Logger.error(`prepare (postgres): ${err}`);
} finally {
client?.release();
}
}
private async createDB() {
const client = new Client({
...this.config.postgres,
database: "postgres"
});
await client.connect();
if ((await client.query(`SELECT * FROM pg_database WHERE datname = '${this.config.postgres.database}'`)).rowCount == 0) {
await client.query(`CREATE DATABASE "${this.config.postgres.database}"
WITH
OWNER = ${this.config.postgres.user}
CONNECTION LIMIT = -1;`
);
}
client.end();
}
private async upgradeDB(fileNamePrefix: string, schemaFolder: string) {
const versionCodeInfo = await this.pool.query("SELECT value FROM config WHERE key = 'version'");
let versionCode = versionCodeInfo.rows[0] ? versionCodeInfo.rows[0].value : 0;
let path = `${schemaFolder}/_upgrade_${fileNamePrefix}_${(parseInt(versionCode) + 1)}.sql`;
Logger.debug(`db update: trying ${path}`);
while (fs.existsSync(path)) {
Logger.debug(`db update: updating ${path}`);
await this.pool.query(this.processUpgradeQuery(fs.readFileSync(path).toString()));
versionCode = (await this.pool.query("SELECT value FROM config WHERE key = 'version'"))?.rows[0]?.value;
path = `${schemaFolder}/_upgrade_${fileNamePrefix}_${(parseInt(versionCode) + 1)}.sql`;
Logger.debug(`db update: trying ${path}`);
}
Logger.debug(`db update: no file ${path}`);
}
private async applyIndexes(fileNamePrefix: string, schemaFolder: string) {
const path = `${schemaFolder}/_${fileNamePrefix}_indexes.sql`;
if (fs.existsSync(path)) {
await this.pool.query(fs.readFileSync(path).toString());
} else {
Logger.debug(`failed to apply indexes to ${fileNamePrefix}`);
}
}
private processUpgradeQuery(query: string): string {
let result = query;
result = result.replace(/sha256\((.*?)\)/gm, "encode(digest($1, 'sha256'), 'hex')");
result = result.replace(/integer/gmi, "NUMERIC");
return result;
}
}

View File

@@ -1,33 +0,0 @@
const { db } = require("./databases");
var config = require('../config.js');
const logger = require('../utils/logger.js');
class Sqlite {
constructor(connection) {
this.connection = connection;
}
getConnection() {
return this.connection;
}
prepare(type, query, params) {
if (type === 'get') {
return this.connection.prepare(query).get(...params);
} else if (type === 'run') {
this.connection.prepare(query).run(...params);
} else if (type === 'all') {
return this.connection.prepare(query).all(...params);
} else {
logger.debug('sqlite query: returning undefined')
logger.debug("prepare: type: " + type + ", query: " + query + ", params: " + params);
return undefined;
}
}
exec(query) {
return this.connection.exec(query);
}
}
module.exports = Sqlite;

108
src/databases/Sqlite.ts Normal file
View File

@@ -0,0 +1,108 @@
import { IDatabase, QueryType } from "./IDatabase";
import Sqlite3, { Database, Database as SQLiteDatabase } from "better-sqlite3";
import fs from "fs";
import path from "path";
import { getHash } from "../utils/getHash";
import { Logger } from "../utils/logger";
export class Sqlite implements IDatabase {
private db: SQLiteDatabase;
constructor(private config: SqliteConfig)
{
}
// eslint-disable-next-line require-await
async prepare(type: QueryType, query: string, params: any[] = []): Promise<any[]> {
// Logger.debug(`prepare (sqlite): type: ${type}, query: ${query}, params: ${params}`);
const preparedQuery = this.db.prepare(Sqlite.processQuery(query));
switch (type) {
case "get": {
return preparedQuery.get(...params);
}
case "all": {
return preparedQuery.all(...params);
}
case "run": {
preparedQuery.run(...params);
break;
}
}
}
// eslint-disable-next-line require-await
async init(): Promise<void> {
// Make dirs if required
if (!fs.existsSync(path.join(this.config.dbPath, "../"))) {
fs.mkdirSync(path.join(this.config.dbPath, "../"));
}
this.db = new Sqlite3(this.config.dbPath, { readonly: this.config.readOnly, fileMustExist: !this.config.createDbIfNotExists });
if (this.config.createDbIfNotExists && !this.config.readOnly && fs.existsSync(this.config.dbSchemaFileName)) {
this.db.exec(Sqlite.processUpgradeQuery(fs.readFileSync(this.config.dbSchemaFileName).toString()));
}
if (!this.config.readOnly) {
this.db.function("sha256", (str: string) => {
return getHash(str, 1);
});
// Upgrade database if required
Sqlite.upgradeDB(this.db, this.config.fileNamePrefix, this.config.dbSchemaFolder);
}
this.db.function("regexp", { deterministic: true }, (regex: string, str: string) => {
return str.match(regex) ? 1 : 0;
});
// Enable WAL mode checkpoint number
if (this.config.enableWalCheckpointNumber) {
this.db.exec("PRAGMA journal_mode=WAL;");
this.db.exec("PRAGMA wal_autocheckpoint=1;");
}
// Enable Memory-Mapped IO
this.db.exec("pragma mmap_size= 500000000;");
}
attachDatabase(database: string, attachAs: string): void {
this.db.prepare(`ATTACH ? as ${attachAs}`).run(database);
}
private static processQuery(query: string): string {
return query.replace(/ ~\* /g, " REGEXP ");
}
private static upgradeDB(db: Database, fileNamePrefix: string, schemaFolder: string) {
const versionCodeInfo = db.prepare("SELECT value FROM config WHERE key = ?").get("version");
let versionCode = versionCodeInfo ? versionCodeInfo.value : 0;
let path = `${schemaFolder}/_upgrade_${fileNamePrefix}_${(parseInt(versionCode) + 1)}.sql`;
Logger.debug(`db update: trying ${path}`);
while (fs.existsSync(path)) {
Logger.debug(`db update: updating ${path}`);
db.exec(this.processUpgradeQuery(fs.readFileSync(path).toString()));
versionCode = db.prepare("SELECT value FROM config WHERE key = ?").get("version").value;
path = `${schemaFolder}/_upgrade_${fileNamePrefix}_${(parseInt(versionCode) + 1)}.sql`;
Logger.debug(`db update: trying ${path}`);
}
Logger.debug(`db update: no file ${path}`);
}
private static processUpgradeQuery(query: string): string {
return query.replace(/^.*--!sqlite-ignore/gm, "");
}
}
export interface SqliteConfig {
dbPath: string;
dbSchemaFileName: string;
dbSchemaFolder: string;
fileNamePrefix: string;
readOnly: boolean;
createDbIfNotExists: boolean;
enableWalCheckpointNumber: boolean
}

View File

@@ -1,81 +0,0 @@
var config = require('../config.js');
var Sqlite3 = require('better-sqlite3');
var fs = require('fs');
var path = require('path');
var Sqlite = require('./Sqlite.js')
var Mysql = require('./Mysql.js');
const logger = require('../utils/logger.js');
const getHash = require('../utils/getHash.js');
let options = {
readonly: config.readOnly,
fileMustExist: !config.createDatabaseIfNotExist
};
if (config.mysql) {
module.exports = {
db: new Mysql(config.mysql),
privateDB: new Mysql(config.privateMysql)
};
} else {
// Make dirs if required
if (!fs.existsSync(path.join(config.db, "../"))) {
fs.mkdirSync(path.join(config.db, "../"));
}
if (!fs.existsSync(path.join(config.privateDB, "../"))) {
fs.mkdirSync(path.join(config.privateDB, "../"));
}
var db = new Sqlite3(config.db, options);
var privateDB = new Sqlite3(config.privateDB, options);
if (config.createDatabaseIfNotExist && !config.readOnly) {
if (fs.existsSync(config.dbSchema)) db.exec(fs.readFileSync(config.dbSchema).toString());
if (fs.existsSync(config.privateDBSchema)) privateDB.exec(fs.readFileSync(config.privateDBSchema).toString());
}
if (!config.readOnly) {
db.function("sha256", (string) => {
return getHash(string, 1);
});
// Upgrade database if required
ugradeDB(db, "sponsorTimes");
ugradeDB(privateDB, "private")
}
// Attach private db to main db
db.prepare("ATTACH ? as privateDB").run(config.privateDB);
// Enable WAL mode checkpoint number
if (!config.readOnly && config.mode === "production") {
db.exec("PRAGMA journal_mode=WAL;");
db.exec("PRAGMA wal_autocheckpoint=1;");
}
// Enable Memory-Mapped IO
db.exec("pragma mmap_size= 500000000;");
privateDB.exec("pragma mmap_size= 500000000;");
module.exports = {
db: new Sqlite(db),
privateDB: new Sqlite(privateDB)
};
function ugradeDB(db, prefix) {
let versionCodeInfo = db.prepare("SELECT value FROM config WHERE key = ?").get("version");
let versionCode = versionCodeInfo ? versionCodeInfo.value : 0;
let path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql";
logger.debug('db update: trying ' + path);
while (fs.existsSync(path)) {
logger.debug('db update: updating ' + path);
db.exec(fs.readFileSync(path).toString());
versionCode = db.prepare("SELECT value FROM config WHERE key = ?").get("version").value;
path = config.schemaFolder + "/_upgrade_" + prefix + "_" + (parseInt(versionCode) + 1) + ".sql";
logger.debug('db update: trying ' + path);
}
logger.debug('db update: no file ' + path);
}
}

View File

@@ -0,0 +1,89 @@
import { config } from "../config";
import { Sqlite } from "./Sqlite";
import { Mysql } from "./Mysql";
import { Postgres } from "./Postgres";
import { IDatabase } from "./IDatabase";
let db: IDatabase;
let privateDB: IDatabase;
if (config.mysql) {
db = new Mysql(config.mysql);
privateDB = new Mysql(config.privateMysql);
} else if (config.postgres?.enabled) {
db = new Postgres({
dbSchemaFileName: config.dbSchema,
dbSchemaFolder: config.schemaFolder,
fileNamePrefix: "sponsorTimes",
readOnly: config.readOnly,
createDbIfNotExists: config.createDatabaseIfNotExist,
postgres: {
user: config.postgres?.user,
host: config.postgres?.host,
database: "sponsorTimes",
password: config.postgres?.password,
port: config.postgres?.port,
max: config.postgres?.max,
min: config.postgres?.min,
}
});
privateDB = new Postgres({
dbSchemaFileName: config.privateDBSchema,
dbSchemaFolder: config.schemaFolder,
fileNamePrefix: "private",
readOnly: config.readOnly,
createDbIfNotExists: config.createDatabaseIfNotExist,
postgres: {
user: config.postgres?.user,
host: config.postgres?.host,
database: "privateDB",
password: config.postgres?.password,
port: config.postgres?.port,
max: config.postgres?.max,
min: config.postgres?.min,
}
});
} else {
db = new Sqlite({
dbPath: config.db,
dbSchemaFileName: config.dbSchema,
dbSchemaFolder: config.schemaFolder,
fileNamePrefix: "sponsorTimes",
readOnly: config.readOnly,
createDbIfNotExists: config.createDatabaseIfNotExist,
enableWalCheckpointNumber: !config.readOnly && config.mode === "production"
});
privateDB = new Sqlite({
dbPath: config.privateDB,
dbSchemaFileName: config.privateDBSchema,
dbSchemaFolder: config.schemaFolder,
fileNamePrefix: "private",
readOnly: config.readOnly,
createDbIfNotExists: config.createDatabaseIfNotExist,
enableWalCheckpointNumber: false
});
}
async function initDb(): Promise<void> {
await db.init();
await privateDB.init();
if (db instanceof Sqlite) {
// Attach private db to main db
(db as Sqlite).attachDatabase(config.privateDB, "privateDB");
}
if (config.mode === "mirror" && db instanceof Postgres) {
const tables = config?.dumpDatabase?.tables ?? [];
const tableNames = tables.map(table => table.name);
for (const table of tableNames) {
const filePath = `${config?.dumpDatabase?.appExportPath}/${table}.csv`;
await db.prepare("run", `COPY "${table}" FROM '${filePath}' WITH (FORMAT CSV, HEADER true);`);
}
}
}
export {
db,
privateDB,
initDb,
};

30
src/index.ts Normal file
View File

@@ -0,0 +1,30 @@
import { config } from "./config";
import { initDb } from "./databases/databases";
import { createServer } from "./app";
import { Logger } from "./utils/logger";
import { startAllCrons } from "./cronjob";
import { getCommit } from "./utils/getCommit";
async function init() {
process.on("unhandledRejection", (error: any) => {
// eslint-disable-next-line no-console
console.dir(error?.stack);
process.exit(1);
});
await initDb();
// edge case clause for creating compatible .db files, do not enable
if (config.mode === "init-db-and-exit") process.exit(0);
// do not enable init-db-only mode for usage.
(global as any).HEADCOMMIT = config.mode === "development" ? "development"
: config.mode === "test" ? "test"
: getCommit() as string;
createServer(() => {
Logger.info(`Server started on port ${config.port}.`);
// ignite cron job after server created
startAllCrons();
}).setTimeout(15000);
}
init();

6
src/middleware/apiCsp.ts Normal file
View File

@@ -0,0 +1,6 @@
import { NextFunction, Request, Response } from "express";
export function apiCspMiddleware(req: Request, res: Response, next: NextFunction): void {
res.header("Content-Security-Policy", "script-src 'none'; object-src 'none'");
next();
}

View File

@@ -1,5 +0,0 @@
module.exports = function corsMiddleware(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
}

Some files were not shown because too many files have changed in this diff Show More