How to get the current_user details in Discourse.Dialect.postProcessText for both client and server side?

Hi,

In my discourse app, I want to mask sensitive content inside posts (email/phone numbers etc.)

I wrote a plugin by following ALL CAPS plugin by @sam.

This is what I came up with

function mask_sensitive_content (text){
  var emailRegex = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/ig;
  var mobileRegex = /\b\+?\d[\d ]{8,12}\d/g;
  
  var emailReplaceWith = ' ---@---.--- ';
  var mobileReplaceWith = ' ########## ';

  return text.replace(mobileRegex, mobileReplaceWith)
    .replace(emailRegex, emailReplaceWith);
}

Discourse.Dialect.postProcessText(function (text) {
  return mask_sensitive_content(text);
});

This masking works both on the client-side and server-side (the data is being written into db after masking).

But I now need to exclude admins and moderators from masking. I looked through several plugins and discussions in meta.discourse and made this:

Discourse.Dialect.postProcessText(function (text) {

  var current_user = null
  if(Discourse.User && Discourse.User.current()){
    current_user = Discourse.User.current();
  }

  // Not masking the content if its an admin or moderator
  if(current_user != null && (current_user.admin == false || current_user.moderato == false)){
    return mask_sensitive_content(text);
  }
});

This works perfectly in the editor, but when I save the content, it is not getting masked. Seems like my code doesn’t have any effect.

On further investigation I found Discourse.User.current() is causing a problem in the backend while trying to cook the content, since Discourse.User is not available there.

Do you have any hints on how I should go about this?

Have a look at

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/pretty-text/engines/discourse-markdown/censored.js.es6 :slight_smile:

2 Likes

@tgxworld Thanks for your reply, But in my case I can’t keep a list of censored words.

My intention is to censor email and phone numbers in the post with an exemption for the admin & moderator ( admin/moderator should be able to post email and mobile number).

Please advice.

I think you misunderstood, he is showing the new way of registering your dialect, and how you can access site settings in the registerOptions nd assign it to opts to be used by your setup function.

1 Like

@cpradio Thanks for the clarification, I was actually using the old plugin interface to manipulate text in the editor.

I tried the new way as shown by @tgxworld, Unfortunately even that didn’t work. I ended up in the same situation. Here is the sample code

import { registerOption } from 'pretty-text/pretty-text';

registerOption((siteSettings, opts) => {
  opts.features["sensitive_content_masking"] = true;
});

function maskSensitiveContent(text, user){
 
  var result = text. //Performing my regex and masking

  if(user !== null && (user.admin === true || user.moderator === true)){
    return text;
  }else{
    return result;
  }
}

export function setup(helper){
  helper.addPreProcessor(text => {
    return maskSensitiveContent(text, helper.getOptions().currentUser);
  });
}

This works perfectly in the editor and I can see int the preview section that the content is getting masked.
But when I save this I am getting error Cannot read property 'admin' of undefined/nTypeError: of around this line
https://github.com/discourse/discourse/blob/master/lib/pretty_text.rb#L162

Seems like currentUser or not even the opts is available in the server side when it try to cook with the V8 context.

You want two cooked per post, one for admin and one for others?

I think one cooked only is stored per post in the DB.

3 Likes

@Falco No, I need only one cooked post.

Consider this example:

Normal user creating a post with the content "contact me in this email xyz@xyz.com"
everyone including admin should see this “contact me in this email —@---.—” The email is masked. I want to save this in DB as cooked.

If admin/moderator creating a post with content “send your queries to support@abc.com everyone should see this “send your queries to support@abc.com (without masking the email).

This is my requirement, how should I go about this?

2 Likes

Hi, I am stuck in this issue, any help? Or any other way to achieve this.