this post was submitted on 25 Jun 2023
53 points (100.0% liked)

Lemmy

12535 readers
2 users here now

Everything about Lemmy; bugs, gripes, praises, and advocacy.

For discussion about the lemmy.ml instance, go to [email protected].

founded 4 years ago
MODERATORS
 

Well I never had spam issues, until 0.18 forced captchas to be disabled. Thankfully the bots just seem to be signing up, not doing much yet. Using fake emails that never get verified.

So I threw together a little script. Just put this in a sh file, and create a cron job or systemd service to run it every 15 minutes or so. Use your favorite text edit tool to replace "thelemmyclub" with your instance name, or whatever you have your docker containers named. (Check docker ps). You'll also have to be able to run docker without sudo, so add your user to the docker group or put the cron job on root (if you do that make sure only root can access the file, for security)

Also if you set up manually without docker, well I'm sure you have the skills to adapt these commands appropriately.

First though run:

docker exec -it thelemmyclub_postgres_1 psql -U lemmy -h 127.0.0.1 -p 5432 -d lemmy -c "select * from local_user where id in (select local_user_id from email_verification where published < (NOW() - INTERVAL '60 minute'));"

This will list all users who haven't completed email verification, except those that are under an hour old. If you think these are all abandoned accounts and bots, carry on. It's always best to check before doing things to live databases...

Edit: thanks to input from @[email protected]

The sh file you need:

#! /bin/bash
docker exec -it thelemmyclub_postgres_1 psql -U lemmy -h 127.0.0.1 -p 5432 -d lemmy -c "DELETE FROM person WHERE local = 'true' AND id IN (SELECT person_id FROM local_user WHERE id IN (SELECT local_user_id FROM email_verification WHERE published < (NOW() - INTERVAL '60 minute')));"

This will delete all users over an hour old who haven't completed email verification. (Only applies to accounts made after you enabled email verification, so older accounts are safe)

Hope this helps!

you are viewing a single comment's thread
view the rest of the comments
[–] sugar_in_your_tea 2 points 1 year ago (1 children)

Should probably use joins in that query:

SELECT * FROM local_user lu
    INNER JOIN email_verification ev ON lu.id = ev.local_user_id
    WHERE published < (NOW() - INTERVAL '60 minute');

It probably doesn't matter for the size of those tables, but might as well do a little better than a subquery.

You could do something similar for the delete statements.

[–] [email protected] 1 points 1 year ago (1 children)

I've simplified it to one line above, see edit. Seems like person is linked to the other tables so just deleting the person entry is enough.

But I'll confess I have little experience with SQL, I'll look into joins.

[–] sugar_in_your_tea 1 points 1 year ago

It could make it run a bit faster. Again, probably not going to be a big deal on the size of these tables, but it's good practice and "the right way."