Skip to content

feat: support anonymous replies (storage + masking + tests) #37#39

Closed
JoshuaNam wants to merge 6 commits intoCMU-313:mainfrom
JoshuaNam:feat/anonymous-replies-fix-clean
Closed

feat: support anonymous replies (storage + masking + tests) #37#39
JoshuaNam wants to merge 6 commits intoCMU-313:mainfrom
JoshuaNam:feat/anonymous-replies-fix-clean

Conversation

@JoshuaNam
Copy link

@JoshuaNam JoshuaNam commented Feb 13, 2026

Changes (Issue #29 + #6)

  • Added backend support for marking replies/posts as anonymous
  • Persisted anonymous flag (0/1) on posts in the database
  • Masked poster identity for non-admin users (uid set to 0, username/display name set to "Anonymous", generic avatar)
  • Preserved real author visibility for admins and exposed isAnonymous=true flag
  • Ensured non-anonymous posts are unaffected
  • Added unit tests covering storage, API masking, admin visibility, topic-level masking, and regression cases

Testing

  1. Run the full backend test suite:
    npm run lint
    npm run test

  2. Verify:

  • Anonymous posts store anonymous=1
  • Regular users see masked identity (uid=0, username "Anonymous")
  • Admins see real author with isAnonymous=true
  • Non-anonymous posts behave normally
  1. Confirm all existing tests pass with no regressions

Related Issues

Resolves #6
Resolves #29

@coveralls
Copy link

coveralls commented Feb 13, 2026

Pull Request Test Coverage Report for Build 22021919621

Details

  • 19 of 19 (100.0%) changed or added relevant lines in 5 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.02%) to 78.901%

Totals Coverage Status
Change from base Build 21973002465: 0.02%
Covered Lines: 25409
Relevant Lines: 30378

💛 - Coveralls

@cirex-web cirex-web closed this Feb 13, 2026
@cirex-web cirex-web reopened this Feb 13, 2026
@cirex-web
Copy link

hmm the auto-deployment doesn't seem to be working... maybe u need to make a branch in this repo instead of in your fork?

@JoshuaNam
Copy link
Author

Hmm alright, I'll make the changes and let you know.

Comment on lines 60 to 62
if (post.anonymous === 1) {
if (isAdmin) {
post.isAnonymous = true;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add another anonymous field here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch... you're right, isAnonymous is redundant. Admins already have post.anonymous === 1 available directly and no frontend template or client-side JS actually reads isAnonymous. I've removed it from summary.js, topics/posts.js, and api/posts.js and updated the tests to assert on post.anonymous instead.

Comment on lines +37 to +39
anonymous:
type: number
description: Whether this post was made anonymously (1 for anonymous, 0 for not)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code changes make sense, pretty good

why is anonymous of type number instead of boolean here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the convention that the other components use

Copy link

@cirex-web cirex-web Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which (existing) components?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This follows the existing NodeBB convention for DB-persisted boolean flags. Specifically: deleted, edited, and uid in PostDataObject (same file, lines 215/227), locked/pinned/scheduled in TopicObject.yaml, and banned/email:confirmed in UserObject.yaml all use type: number with 0/1 values. Since anonymous is stored as 0/1 in the DB and returned as-is (not converted to a boolean in processing code), type: number is consistent here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough

src/api/posts.js Outdated
Comment on lines 52 to 62
uid: 0,
username: 'Anonymous',
displayname: 'Anonymous',
userslug: '',
picture: '',
signature: '',
status: 'offline',
'icon:text': '?',
'icon:bgColor': '#aaa',
};
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this code being used in the frontend btw? I see it's being used for the /api/v3/posts/:pid endpoint (see src/routes/write/posts.js), but I can't find the frontend code that calls this endpoint

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that the frontend doesn't call /api/v3/posts/:pid directly for this. The masking in postsAPI.get() works for single-post fetches, but I found a gap: postsAPI.getReplies() (used by the "Show Replies" button via public/src/client/topic/replies.js:17) doesn't apply any anonymous masking. I've fixed this by extracting a shared Posts.anonymizePost() helper and applying it in getReplies() as well, so anonymous authors are masked consistently across all paths.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea that's actualy good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Anonymous Replies Store anonymous flag in database

3 participants

Comments