add updates to voting plugin

This commit is contained in:
2023-10-25 15:48:05 +02:00
parent ee6d73a4cf
commit d66fdb7c58
3 changed files with 462 additions and 34 deletions

View File

@@ -0,0 +1,298 @@
nig
cum
pron
jap
xxx
cok
kkk
Africoon
akata
Beaner
Camel jockey
Chink
Coon
Coonass
Dune Coon
Gook
Jungle Bunny
Niglet
Nignog
Porch Monkey
Towel Head
Turk
Wetback
Wigger
Cock
Fag
Kock
Pecker
Tit
Wang
wank
Willy
Willies
Anal
Slut
Retard
Retarded
niga
Raped
Rape
Rapist
Semen
Cums
Cum
Fag
Fags
Tit
Porn
Slut
Smut
Teets
Tits
Jiz
doosh
Dick
Cunt
Boob
scat
slut
twat
pube
pubes
twat
retards
rimming
milf
nazi
orgy
porn
pussy
niggar
Nigga
Nigger
assfucker
assfucka
b00b
b00bs
ballsack
beastial
beastiality
bestial
bestiality
blow job
blowjob
blowjobs
boner
boobs
booobs
boooobs
booooobs
buttplug
c0ck
c0cksucker
chink
cl1t
clit
clitoris
clits
cock-sucker
cockface
cockhead
cockmunch
cockmuncher
cocks
cocksuck
cocksucked
cocksucker
cocksucking
cocksucks
cocksuka
cocksukka
cokmuncher
coksucka
cummer
cumshot
cunilingus
cunillingus
cunnilingus
cuntlick
cuntlicker
cuntlicking
cunts
cyalis
cyberfuc
cyberfuck
cyberfucked
cyberfucker
cyberfuckers
cyberfucking
d1ck
dickhead
dildo
dildos
dog-fucker
doggin
dogging
donkeyribber
doosh
duche
Douche
ejaculate
ejaculated
ejaculates
ejaculating
ejaculatings
ejaculation
ejakulate
F4nny
fagging
faggitt
faggot
faggs
fagot
fagots
fatass
felching
fellate
fellatio
fingerfuck
fingerfucked
fingerfucker
fingerfuckers
fingerfucking
fingerfucks
fistfuck
fistfucked
fistfucker
fistfuckers
fistfucking
fistfuckings
fistfucks
fuckhead
fuckheads
fuckingshitmotherfucker
fuckme
fuckwhit
fuckwit
fukwit
fukwhit
gangbang
gangbanged
gangbangs
gaysex
goatse
hardcoresex
horniest
horny
hotsex
jack-off
jackoff
jerk-off
jism
jizm
jizz
kawk
kondum
kondums
kummer
humming
kunilingus
l3i+ch
l3itch
labia
m0f0
m0fo
m45terbate
ma5terb8
ma5terbate
masochist
master-bate
masterb8
masterbat*
masterbat3
masterbate
masterbation
masterbations
masturbate
nig
n1g
n1gga
n1gger
nazi
nigg3r
nigg4h
nigga
niggah
niggas
niggaz
nigger
niggers
nutsack
orgasim
orgasims
orgasm
orgasms
p0rn
penis
phonesex
penisfucker
phuck
phuk
phuked
phuking
phukked
phukking
phuks
pigfucker
pissoff
porno
pornography
pornos
pusse
pussi
pussies
pussy
pussys
rectum
rimjaw
sadist
schlong
scrotum
shaggin
shagging
shitdick
shited
shitfuck
shithead
sluts
smegma
spunk
t1tt1e5
t1tties
testical
testicle
titfuck
tittie5
tittiefucker
titties
tittyfuck
tittywank
titwank
tw4t
twathead
twatty
twunt
twunter
v14gra
v1gra
vagina
viagra
vulva
w00se
wanker
wanky
whore
xrated
hitler
putin

View File

@@ -11,6 +11,7 @@ createApp( {
hasLoadedBasics: false, hasLoadedBasics: false,
hasLoadedVotes: false, hasLoadedVotes: false,
sorting: 'newest', sorting: 'newest',
userIdentifier: '',
}; };
}, },
computed: { computed: {
@@ -44,12 +45,67 @@ createApp( {
} }
} }
}, },
computed: {
orderedVotes() {
if ( this.sorting === 'oldest' ) {
return Object.values( this.entries );
} else if ( this.sorting === 'newest' ) {
const ent = Object.keys( this.entries ).reverse();
let ret = [];
for ( let entry in ent ) {
ret.push( this.entries[ ent[ entry ] ] );
}
return ret;
} else {
let ent = Object.keys( this.entries ).sort( ( a, b ) => {
if ( this.sorting === 'nameUp' ) {
return this.entries[ a ].title.localeCompare( this.entries[ b ].title );
} else if ( this.sorting === 'nameDown' ) {
return this.entries[ b ].title.localeCompare( this.entries[ a ].title );
} else if ( this.sorting === 'mostVoted' ) {
return this.entries[ b ].count - this.entries[ a ].count;
} else if ( this.sorting === 'leastVoted' ) {
return this.entries[ a ].count - this.entries[ b ].count;
}
} );
let ret = [];
for ( let entry in ent ) {
ret.push( this.entries[ ent[ entry ] ] );
}
return ret;
}
}
},
methods: { methods: {
getData() { getData() {
fetch( '/polls/get/' + location.pathname.substring( 7 ) ).then( response => { fetch( '/polls/get/' + location.pathname.substring( 7 ) ).then( response => {
response.json().then( data => { response.json().then( data => {
this.entries = data; this.entries = data;
this.hasLoadedVotes = true; this.fingerprint();
let fetchOptions = {
method: 'post',
body: JSON.stringify( { 'fingerprint': this.userIdentifier } ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
},
};
fetch( '/voting/getVotedOn/' + location.pathname.substring( 8 ), fetchOptions ).then( res => {
if ( res.status === 200 ) {
res.json().then( json => {
this.votedOn = JSON.parse( localStorage.getItem( 'itemsVotedOn' ) ?? '{}' );
for ( let el in json ) {
if ( json[ el ] === 1 ) {
this.votedOn[ json[ el ] ] = 'up';
} else if ( json[ el ] === -1 ) {
this.votedOn[ json[ el ] ] = 'down';
}
}
localStorage.setItem( 'itemsVotedOn', JSON.stringify( this.votedOn ) );
this.hasLoadedVotes = true;
} );
}
} );
} ); } );
} ); } );
fetch( '/polls/getDetails/' + location.pathname.substring( 7 ) ).then( response => { fetch( '/polls/getDetails/' + location.pathname.substring( 7 ) ).then( response => {
@@ -60,23 +116,29 @@ createApp( {
} ); } );
this.votedOn = JSON.parse( localStorage.getItem( 'itemsVotedOn' ) ?? '{}' ); this.votedOn = JSON.parse( localStorage.getItem( 'itemsVotedOn' ) ?? '{}' );
}, },
fingerprint() {
// I am forced to do this because there are idiots in this world
// https://stackoverflow.com/questions/27247806/generate-unique-id-for-each-device
if ( !this.userIdentifier ) {
const navigator_info = window.navigator;
const screen_info = window.screen;
let uid = navigator_info.mimeTypes.length;
uid += navigator_info.userAgent.replace( /\D+/g, '' );
uid += navigator_info.plugins.length;
uid += screen_info.height || '';
uid += screen_info.width || '';
uid += screen_info.pixelDepth || '';
this.userIdentifier = uid;
}
},
save() { save() {
if ( this.newSuggestion.comment && this.newSuggestion.title ) { if ( this.newSuggestion.comment && this.newSuggestion.title ) {
let alreadyExists = false; let alreadyExists = false;
for ( let el in this.entries ) { for ( let el in this.entries ) {
if ( this.entries[ el ][ 'title' ] === this.newSuggestion.title ) { if ( this.entries[ el ][ 'title' ].toLocaleLowerCase() === this.newSuggestion.title.toLocaleLowerCase() ) {
alreadyExists = true; alreadyExists = true;
} }
} }
if ( alreadyExists ) {
if ( confirm( 'An element with the same title exists already. Do you really want to add another one?' ) ) {
if ( confirm( 'Are you really sure?' ) ) {
alreadyExists = true;
} else {
alreadyExists = false;
}
}
}
if ( !alreadyExists ) { if ( !alreadyExists ) {
let fetchOptions = { let fetchOptions = {
method: 'post', method: 'post',
@@ -86,19 +148,25 @@ createApp( {
'charset': 'utf-8' 'charset': 'utf-8'
}, },
}; };
fetch( '/voting/add/' + location.pathname.substring( 8 ), fetchOptions ).then( response => { fetch( '/polls/add/' + location.pathname.substring( 8 ), fetchOptions ).then( response => {
if ( response.status !== 200 ) { if ( response.status === 418 ) {
alert( 'One or more of the words in either your description or title is on our blocklist. Please make sure that you are not using any words that are NSFW, racist or similar.' );
} else if ( response.status !== 200 ) {
alert( 'there was an error updating' ); alert( 'there was an error updating' );
} else {
this.closePopup();
this.getData();
} }
} ); } );
this.closePopup(); } else {
this.getData(); alert( 'An entry with this name exists already. Please vote on that entry.' );
} }
} else { } else {
alert( 'Not all required fields are filled out!' ); alert( 'Not all required fields are filled out!' );
} }
}, },
vote( type, suggestionID ) { vote( type, suggestionID ) {
this.fingerprint();
let voteType = type; let voteType = type;
let didDeactivate = false; let didDeactivate = false;
if ( this.votedOn[ suggestionID ] === type ) { if ( this.votedOn[ suggestionID ] === type ) {
@@ -113,14 +181,16 @@ createApp( {
} }
let fetchOptions = { let fetchOptions = {
method: 'post', method: 'post',
body: JSON.stringify( { 'voteType': voteType, 'id': suggestionID } ), body: JSON.stringify( { 'voteType': voteType, 'id': suggestionID, 'fingerprint': this.userIdentifier } ),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'charset': 'utf-8' 'charset': 'utf-8'
}, },
}; };
fetch( '/polls/vote/' + location.pathname.substring( 7 ), fetchOptions ).then( response => { fetch( '/polls/vote/' + location.pathname.substring( 7 ), fetchOptions ).then( response => {
if ( response.status !== 200 ) { if ( response.status === 409 ) {
alert( 'You have already voted on this!' );
} else if ( response.status !== 200 ) {
alert( 'there was an error updating' ); alert( 'there was an error updating' );
} else { } else {
this.votedOn[ suggestionID ] = didDeactivate ? undefined : voteType; this.votedOn[ suggestionID ] = didDeactivate ? undefined : voteType;

View File

@@ -40,6 +40,32 @@ const runSave = () => {
} ); } );
}; };
// There are idiots in this world so we have to filter
// Filter list is from here: https://github.com/BurntRouter/filtered-word-lists plus some extra words
let uidCrossReference = JSON.parse( fs.readFileSync( path.join( __dirname + '/data/voteUIDReferencing.json' ) ) );
const fl = '' + fs.readFileSync( path.join( __dirname + '/data/filterlist.txt' ) );
let votingDirections = { '1': 'up', '-1': 'down' };
let filterList = [];
let prevStart = 0;
for ( let e in fl ) {
if ( fl[ e ] === '\n' ) {
filterList.push( fl.slice( prevStart, e ).toLocaleLowerCase() );
prevStart = parseInt( e ) + 1;
}
}
const filtering = ( string ) => {
// using these filter lists: https://github.com/BurntRouter/filtered-word-lists plus some extra words
// returns true if text is ok
const str = string.toLocaleLowerCase();
for ( let badWord in filterList ) {
if ( str.includes( filterList[ badWord ] ) ) {
return false;
}
}
return true;
};
module.exports = ( app ) => { module.exports = ( app ) => {
app.get( '/polls/:vote', ( req, res ) => { app.get( '/polls/:vote', ( req, res ) => {
res.sendFile( path.join( __dirname + '/html/voting.html' ) ); res.sendFile( path.join( __dirname + '/html/voting.html' ) );
@@ -58,6 +84,10 @@ module.exports = ( app ) => {
res.send( JSON.parse( filedata )[ req.params.vote ] ?? {} ); res.send( JSON.parse( filedata )[ req.params.vote ] ?? {} );
} ); } );
} ); } );
app.post( '/polls/getVotedOn/:vote', ( req, res ) => {
res.send( uidCrossReference[ req.body.fingerprint ] ?? {} );
} );
app.get( '/polls/get/:vote', ( req, res ) => { app.get( '/polls/get/:vote', ( req, res ) => {
res.send( votingMemCache[ req.params.vote ] ); res.send( votingMemCache[ req.params.vote ] );
@@ -65,34 +95,64 @@ module.exports = ( app ) => {
app.post( '/polls/vote/:vote/', bodyParser.json(), ( req, res ) => { app.post( '/polls/vote/:vote/', bodyParser.json(), ( req, res ) => {
// up / down-voting // up / down-voting
if ( votingMemCache[ req.params.vote ] ) { if ( req.body.fingerprint != '' ) {
if ( votingMemCache[ req.params.vote ][ req.body.id ] ) { if ( uidCrossReference[ req.body.fingerprint ] ) {
if ( req.body.voteType === 'up' ) { if ( uidCrossReference[ req.body.fingerprint ][ req.params.vote ] ) {
votingMemCache[ req.params.vote ][ req.body.id ].count += 1; if ( uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ] !== 0 ) {
} else if ( req.body.voteType === 'down' ) { const vote = uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ];
votingMemCache[ req.params.vote ][ req.body.id ].count -= 1; if ( votingDirections[ vote ] === req.body.voteType ) {
res.status( 409 ).send( 'alreadyVotedOn' );
return;
}
} else {
uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ] = 0;
}
} else {
uidCrossReference[ req.body.fingerprint ][ req.params.vote ] = {};
} }
saveVotingData();
res.send( 'ok' );
} else { } else {
res.status( 404 ).send( 'No Entry on this vote with' ); uidCrossReference[ req.body.fingerprint ] = {};
uidCrossReference[ req.body.fingerprint ][ req.params.vote ] = {};
uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ] = 0;
}
if ( votingMemCache[ req.params.vote ] ) {
if ( votingMemCache[ req.params.vote ][ req.body.id ] ) {
if ( req.body.voteType === 'up' ) {
votingMemCache[ req.params.vote ][ req.body.id ].count += 1;
uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ] += 1;
} else if ( req.body.voteType === 'down' ) {
votingMemCache[ req.params.vote ][ req.body.id ].count -= 1;
uidCrossReference[ req.body.fingerprint ][ req.params.vote ][ req.body.id ] -= 1;
}
saveVotingData();
res.send( 'ok' );
} else {
res.status( 404 ).send( 'No Entry on this vote with' );
}
} else {
res.status( 404 ).send( 'No Vote with this ID' );
} }
} else { } else {
res.status( 404 ).send( 'No Vote with this ID' ); res.status( 400 ).send( 'Wrong request' );
} }
} ); } );
app.post( '/polls/add/:vote', bodyParser.json(), ( req, res ) => { app.post( '/polls/add/:vote', bodyParser.json(), ( req, res ) => {
let data = req.body; let data = req.body;
if ( data.title && data.comment ) { if ( data.title && data.comment ) {
if ( !votingMemCache[ req.params.vote ] ) { if ( filtering( data.title ) && filtering( data.comment ) ) {
votingMemCache[ req.params.vote ] = {}; if ( !votingMemCache[ req.params.vote ] ) {
votingMemCache[ req.params.vote ] = {};
}
const id = parseInt( Object.keys( votingMemCache[ req.params.vote ] )[ Object.keys( votingMemCache[ req.params.vote ] ).length - 1 ] ?? 0 ) + 1;
votingMemCache[ req.params.vote ][ id ] = data;
votingMemCache[ req.params.vote ][ id ][ 'id' ] = id;
votingMemCache[ req.params.vote ][ id ][ 'count' ] = 1;
saveVotingData();
res.send( 'ok' );
} else {
res.status( 418 ).send( 'seriously?' );
} }
const id = parseInt( Object.keys( votingMemCache[ req.params.vote ] )[ Object.keys( votingMemCache[ req.params.vote ] ).length - 1 ] ?? 0 ) + 1;
votingMemCache[ req.params.vote ][ id ] = data;
votingMemCache[ req.params.vote ][ id ][ 'id' ] = id;
votingMemCache[ req.params.vote ][ id ][ 'count' ] = 1;
res.send( 'ok' );
} else { } else {
res.status( 400 ).send( 'incomplete' ); res.status( 400 ).send( 'incomplete' );
} }