Check names, phone numbers and bare URLs in spam dashboards [sc-46591] - #3616
Open
EliezerIsrael wants to merge 1 commit into
Open
Check names, phone numbers and bare URLs in spam dashboards [sc-46591]#3616EliezerIsrael wants to merge 1 commit into
EliezerIsrael wants to merge 1 commit into
Conversation
Spammers moved to the first and last name fields, which neither dashboard checked. Names live on the Django User record, not in the Mongo profile doc, so the profile query could not reach them. The slug is checked and is built from the name at signup, but a name edit never regenerates it, so signing up benign and renaming afterwards evaded the check entirely. Names are now matched in Postgres and folded back into the Mongo query by user id, with first and last concatenated so that a phone number split across the two fields is still caught. Free text is now checked for phone numbers and bare URLs rather than href markup alone. That rule lives in the new sefaria/spam.py as spam_text_clauses() and both dashboards point it at their own fields, so the sheet dashboard picks up the same coverage -- it previously matched href only. Links back to Sefaria stay excluded, matching the carve-out the existing href check already made. The phone pattern wants 9+ digits so that prose like a 2020-2024 date range is not read as a phone number. The trade is that a bare 7 digit local number is missed, having the same shape as a year range. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📊 Code Quality Score: 31/100
Was this score accurate? 👍 Yes · 👎 No Scored by GitVelocity · How are scores calculated? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Shortcut: https://app.shortcut.com/sefaria/story/46591
The vector
Spammers moved to the first and last name fields, which neither spam dashboard checked.
Names live on the Django
Userrecord in Postgres, not in the Mongo profile doc, soprofile_spam_dashboard's query could not reach them. Theslugis checked and is built from the name at signup — butUserProfile.save()pushes a name edit to the DjangoUserwithout regenerating the slug. Sign up as "Miriam Cohen", then rename to "Coinbase Support", and the slug staysmiriam-cohenforever. The check was evaded entirely.Changes
sefaria/spam.pyholds the patterns as one source of truth.1-800/555-1234) is still caught.hrefmarkup. That rule isspam_text_clauses(), and both dashboards point it at their own fields — sosheet_spam_dashboardpicks up the same coverage, having previously matchedhrefonly.Trade-offs worth a reviewer's eye
2020-2024date range is not read as a phone number. The cost is that a bare 7-digit local number is missed — it has the same shape as a year range, and spam numbers carry an area or country code anyway.$orgrows from 4 regex branches to 12, on a candidate set already narrowed bydateCreated,owner,includedRefsandsources.ref.__iregex, so those patterns stay inside the regex subset Postgres, Python and PCRE share — no\b,\dor lookarounds. The free-text URL variant runs only in Mongo and does use a lookahead.Tests
sefaria/tests/spam_dashboard_test.py. The negative cases carry the weight, since the only action this queue offers is irreversible deletion:Miriam Cohenmust not read as the.coTLD,Jean-Pierre St.ClairandB. Cohenmust survive the URL pattern,2020-2024andBorn 1948. Teaching since 1975.must not read as phone numbers, and text linking to sefaria.org must stay clear.Verified locally by driving the test functions against a real
auth_usertable in SQLite (35/35). The repo's pytest suite could not start in my environment —sefaria/settings.py:404raisesNameError: APPLE_SSO_IOS_BUNDLE_IDwithout the SSO entries in local_settings, pre-existing and unrelated to this branch. CI is the real gate, both for pytest proper and for Postgresiregex.🤖 Generated with Claude Code