Duplicate email address in MongoDB - javascript

Gmail treats any email with dot (.) in it as the same as without dots. For example mail sent to hello#gmail.com or he.ll.o#gmail.com or he.llo#gmail.com will be sent to the same address. How will you store this in the database so that you avoid duplicate usage of emails with dots in it. For example if a user registers first with salman.khan#gmail.com , he should not be able to use any variation of the same email like sal.mankhan#gmail.com or salman.khan#gmail.com . (Assume the database have 10M of users).

You could remove .'s prior to saving them on the server, eg...
let emailone = "hello#gmail.com"
let emailtwo = "hel.lo#gmail.com"
const normaliseEmails = email => email.split('#')[0].replaceAll(".", "") + "#" + email.split('#')[1]
console.log(normaliseEmails(emailone))
console.log(normaliseEmails(emailtwo))

It's good you're thinking about this, as it can bite you later. Unless you are never going to use or reflect back the email address of a user, you'll likely want to keep the dots so you can show them. So what to do?
If this is important problem to solve, I'd add a second column to your database, a canonical email. This would be the email addresses without the dots. Then, when looking up email addresses, "canonize" the input by removing the periods, and then look it up using this column.
Your database may be able to do this dynamically for you, depending on its features. Be cognizant that this might not be performant as the database grows, but may be okay short term.
You may also want consider other "features" of email addresses, such as the ability to add optional stuff before the #, as in joe+duplicate#example.com, which gets routed to joe#example.com. This is likely fine, but you may want to guard against it as well.

Related

How do I generate a unique code based on the content?

Picture that you're typing in a input. For each character you add (including special characters, like # . # ¤ % & ~ and so on), a unique code will generate based on the content. Not a hash! This unique code will only be 20 characters long.
Example
This is just an example becomes H59S7Y54CI6M7S2XX8A9
This is another example becomes C77KE95HIAJ7VN582758
Hello! I am a example string! becomes Y8BV572SF8U76RXVB944
This is just an example becomes H59S7Y54CI6M7S2XX8A9
Why I want this
I am working on a project where the visitors can login to their own accounts (if they have one). As soon as they type in their email address and password, a unique code will generate based on the string (in a hidden input), so the website can identify the user and get the right data from the database.
Why do I want it?
I encrypt everything in the database with 256-bit AES and each user have their own encryption key. To identify the entered email address and password (which is encrypted with the websites encryption key until they login for the first time), this unique code (based on the string) will identify the login. To do the identification of the login with the websites encryption keys is therefore impossible. Hence my question.
This can maybe be a security risk since the unique code will be stored in the databased hashed in MD5 or Whirlpool, but I have no idea of how I can identify the login in another way. If you know a better way, please tell me.
So, how do I accomplish this? Is it even possible to do?
I know how to generate a unique code which is not based on the content (for an example, generating passwords), but I don't know how to generate a code that are unique based on the content.
I don't know the purpose, but replying directly to your question on how to generate a unique code which is based on the content, you can have something like this
function symmetricEncode(content){
var output = [];
for (var i=0; i<content.length; i++){
output.push(String.fromCharCode(~ content[i].charCodeAt()));
}
return output.join("");
}
var string = "Hey you there";
var code = symmetricEncode(string);
console.log("string to code: ", string);
console.log("code: ", code);
console.log(typeof code);
console.log("decoded code: ", symmetricEncode(code));
This code is not merely a hash, because you can decode it, meaning it is unique, that is, for every input, you get an unique output
Other types of hashes (for example multiplying all the characters) do not fulfil these criteria, because for two different inputs you may get the same output (very unlikely though possible), not being then purely reversible. The ~ makes reference to the bitwise not operator.

Javascript Arrays - Ensuring each batch has a certain element

I have an email script that reads in emails from a database and collects them into one huge object. Now these emails can be BCC, CC, TO type emails which must be passed to our email provider via an API in their respective type.
Their API allows batches up to 1000 emails which isn't the issue. The issue is that in each batch I have to have one TO address at least. In other words say by chance a batch has 1000 'BCC' type emails in it and not one 'TO' type email addresses. Those 1000 emails will not get sent. When you are dealing with 20,000 emails there are 20 batches created and there could very well be a batch that has all BCC or CC type emails with none of them being a TO type address.
So my question is how can I assure a TO address is in each batch during processing?
Some code along with the current output is below.
while (addresses.length > 0) {
// I do some processing here. The addresses above is a map of emails that
// Something like: [ { label: 'to', address: 'jay#someaddress.com' } ].
// Then the processing removes the individual labels from each email and slams
// them into one key value for each email type using a filter function. We also
// append some other things that must be separated as well like the recipient
// variables. The sent information looks like this to our email provider.
{
from: 'jay99#someaddress.com',
subject: 'fff',
text: 'fff',
to: ['jay+3#someaddress.com', 'jay+8#someadd.com'],
bcc: [],
* * // WHAT happens here if all the email addresses reside here and none above in the 'TO' label? The email will fail. The code must ensure at least one 'TO' type address in each batch of 1000.**
cc: [],
'recipient-variables': {
'jay+3#someaddress.com': {},
'jay+8#someadd.com': {}
}
}
}
My initial thought was to randomize it some how but wasn't sure how to do that. I think you almost have to do something to the initial array before it even gets into putting the emails into the right slots (IE type of emails). Suggestions? And thank you for taking the time to read my question. :)
Randomizing the combinations will not solve your problem either, since it does in no way guarantee that there is a 'to' recipient in all of your batches.
One way to solve this issue would be to create to buckets of recipients, one with all 'to' recipients, and another one with all others. This shouldn't be too hard, given that you have the complete list of addresses.
Then always take one 'to' address and 999 other addresses, package them into a batch and send them off. Repeat until either one of the buckets is empty. If the others bucket is empty first, only take the remaining 'to' recipients and send off the email until they are all gone as well.
If your 'to' bucket is empty first, you will have to come up with a different solution. Maybe make up dummy recipients?

ArrayCollection (Collection of forms) index collision in Symfony 2

I am using Symfony2 to build up my page.
When I try to update a collection of forms (like described in the cookbook entry "How to Embed a Collection of Forms"), i get a collision of the indexes of the frontend and the indexes of the ArrayCollection in the backend.
I've got the relation User <-> Address (OneToMany). A user wants to create/update/delete his addresses, therefore he can add / delete in the frontend with the help of the javascript part new address elements. He does the following:
(1) Adds new address (has index: 0)
(2) Adds new address (has index: 1) and instantly removes this address again
(3) Adds new address (has index: 2).
When he clicks on save button, the following code saves/updates the user (and its addresses):
$this->em->persist($user);
$this->em->flush();
New addresses for example are then correctly persisted to the database.
Now the user wants to update the address e.g. with index 0.
When he now clicks on the save button, it updates the adress with "index 0", but at the same time, it adds again the address with "index 2" to the database (object).
To better understand the problem, i've drawn a small illustration (handmade, sorry for my bad art skills):
Now , i've got two times the address with "index 1" within my object / database.
I know why this happens, it's because the first "index 1" address gets mapped to the ArrayCollection element "number 1", and the second gets mapped to "number 2 "(because of the frontend name "index 2").
You can say: "it just fills up the addresses, until it reaches the frontend index in the backend"..
But how can I fix this behaviour ?
Site note:
This behaviour occurs using ajax requests, because if you would reload the page after clicking "save button", it would reindex the addresses in the frontend correctly with the indexes in the backend.
My suggestion to handle that situation:
Reindexing the frontend indexes after clicking save with the server side
indexes. Is this a clear / the only solution for my problem?
Yes, this is problem of Symfony form collection and it has no easy solution imho. But I have to ask why don't you do exactly the same thing what page refresh does? You can refresh only html snippet with collection. HTML code for snippet can come from server-side. Back to your question - yes, reindexing is good solution until you do not want to try write custom collection type on your own.
symfony/symfony/issues/7828
There is similar problem with validating in collection - symfony/symfony/issues/7468.
Well I think default collection type and the tutorial in Symfony docs has the some drawbacks. Hope that's help.
I have come round this issue on the client side by modifying the Javascript/Jquery code given in the Symfony Documentation.
Instead of numbering the new elements by counting the sub-elements, I am looking at the last element's id and extracting its index with a regular expression.
When adding an element, I am incrementing the last index by 1. That way, I never use the same index.
Here is my code :
// Initializing default index at 0
var index = 0;
// Looking for collection fields in the form
var $findinput = $container.find(':input');
// If fields found then looking for last existing index
if ( $findinput.length > 0 ) {
// Reading id of last field
var myString = $findinput.last().attr('id')
// Setting regular expression to extract number from id containing letters, hyphens and underscores
var myRegex = /^[-_A-Za-z]+([0-9]+)[-_A-Za-z]*$/
// Executing regular expression on last collection field id
var test = myRegex.exec(myString);
// Extracting last index and incrementing by 1
if (test.length > 0) index = parseInt(test[1]) + 1;
}
I ran into this problem a couple of times during the past two years. Usually, following the Symfony tutorial How to Embed a Collection of Forms does the job just fine. You need to do a little bit javascript coding to add the "edit/update" functionality, but other than that - you should be just fine using this approach.
If, on the other hand, you have a really complex form which uses AJAX to validate/save/calculation/business logic/etc, I've found it's usually a better to store the final data into an array in the session. After submitting the form, inside the if($form->isValid()){...} block, you would have
$collection = new ArrayCollection($mySessionPlainArray);
$user->setAddress($collection);
I would like to warn you to be careful with the serialization of your data - you might get some awkward exceptions or misbehavior if you're using entities (see my question).
I'm sorry I can't provide more code, but the solution to this problem sometimes is quite complex.

How do I save the first users selections, then generate a unique code/link, and finally display the first users selections for a subsequent user?

I want to create a web page with selections then when a user inputs their selections I would like an output of a code (or even better a unique url) which can be copy-pasted to forums, e-mailed etc... Allowing their friends to click the link and retrieve the input selections associated with that link.
A code would be fine where a link + a code that is copy/pasted into a text box then generated the shared entries.
So for instance I have several drop down boxes:
A drop down with 50 states, a drop down with gender, a drop down with
ages 1-100, a drop down with number of kids.
An end-user comes and selects whatever choices they want and the page
produces the link or code allowing future end-users to either click
the link (preferable) or paste the code into a text box which then
selects all the appropriate selections wishing to be shared. This
allows the second user to view exactly what the first user wanted to
share with a simple short link/code.
I am stuck and I know I don't have to create a unique webpage for each possibility but I'm not sure how to approach.
How do I save the first users selections, then generate a unique code/link, and finally display the first users selections for a subsequent user?
What you probably want are url parameters..
Here's a function that uses regex to grab a param from the url
function gup( name ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null ) return "";
else return results[1];
}
I wouldn't sweat what's going on in there.. but to use it you'ld have a url (mysite.com/coolPage) if they go there with a parameter (mysite.com/coolPage?whosCool=ImCool)
you can, in your javascript call gup("whosCool") and it'll return "ImCool"
in your example, you'ld have mySite.com?state=oklahoma&gender=male
in your javascript you can, on load:
document.getElementById('state').value = gup('state');​​​​​​​​​​
document.getElementById('gender').value = gup('gender');​​​​​​​​​​
to build the url, when they make all of their selections you'll build the url with the parameters.
var url = "mycoolSite.com/mypage?";
url += "state=" + document.getElementById('state').value;
url += "gender=" + document.getElementById('gender').value;
document.getElementById('outputURL').innerHTML = "<a href='"+url+"'>Your url</a>";
That's the pieces, you'll have to build it all together though
I can think of two ways to do this:
Unique database id which stores all the information for that user and is generated when they generate the link.
A much longer url with all the options stored as parameters on the end.
Database solution
When the user clicks to generate the link I'd take all the information gathered from the page, and push it through in a form for processing. I'd then store all the information in a database with a unique id and pass that id back to the user, storing it as a parameter in the url that is in the generated link.
When the user clicks the link the first thing you could do on page load is to query the id parameter and display all the database fields that have been previously stored.
Depending on whether you have any PHP knowledge, you might find these links useful:
https://gist.github.com/webaware/4048580
http://www.dynamicdrive.com/forums/showthread.php?45895-How-to-populate-php-html-form-with-MySQL-data
URL parameters solution
I'd again gather all the information from the page and push it through in a form before building a link with the parameters listed out. So www.tester.com?gender=female etc.
When the user clicks the link the first thing you could do on page load is to pull the parameters from the link and display them against the appropriate inputs.
This might get you off the ground with the basics for doing this with javascript.
Pre-fill form field via URL in html
Get the info from the form: How to save data from a form with HTML5 Local Storage?
This one will be particularly helpful to you: How can I pre-populate html form input fields from url parameters?
This second option is definitely messier and I'd probably go with the first option myself.
Hopefully they both make sense - any questions then just ask!

How can I reformat form input before POST using Javascript (or Rails)?

I have a field in my form labeled "Name" that will contain both the First & Last name.
Our existing dynamic server (to which the form is being POSTed to), expects two separate fields (first name, last name).
Can I use Javascript to split the user input into two separate variables before the form is posted to the server? How would I do this?
You should not rely on client side parsing whenever possible. If you are sending this form to an app you can't modify, use the Javascript method mentioned above because you have no control over it (but then why not just have a first and last name field). But if you are controller the backend app, perform all your massaging and data validation there.
Javascript should only be used to enhance the UI experience, not perform import data manipulation, it can be both a security hole and a point of failure if use Javascript for these important tasks.
Also, when manipulating names, keep in mind all the different kinds of formats you will get, such as:
John Smith Jr
Dr John Smith
John Smith Esq.
John Smith IV
John A Smith
So be careful, massaging names is very messy business and the public will enter whatever they want, at the very least, add a small label and ask them to only enter "first and last name" and pray for the best.
I would process this on the server end to make sure the data that is passed is accurate from what was posted. It's relatively easy programmatically to split the name, but the problem is how do you define your separator. Most would agree to split it wherever there is a white-space character, but what if they enter a three word name such as Don Juan DiMarco? If you decide to split the name based on whitespace, you'll have to determine how to assign the first and last names.
$arrNames = preg_split('/\s+/', $_POST['name']);
The above will give you (in PHP) an array of values split by white space. Running that on the string Don Juan DiMarco would give you an array like:
Array([0] => "Don", [1] => "Juan", [2] => "DiMarco")
From there you have to determine which ones are the first name, and which are a middle, and which are a last name. It gets even harder if you have 4 or 5 names entered, which is entirely realistic for certain cultures. All of this is guesswork, which is why I would recommend simply adding a Last Name input field on the front-end. This would eliminate all guess work as to which name is the first name and which is the last name.
If it needs to be handled on client-side, Use the Javascript split method to parse the name field value. Then append the two names to the form's url or create a couple of hidden fields.
You can do something like this:
var yourForm = document.getElementById('yourFormId');
yourform.onsubmit = new function()
{
var nameBox = document.getElementById('nameBox');
var fname = document.createElement('INPUT');
var lname = document.createElement('INPUT');
fname.type = 'HIDDEN';
lname.type = 'HIDDEN';
fname.name = 'fname';
lname.name = 'lname';
var tokens = nameBox.value.split(' ');
// Note there are a million ways to break this parser, demonstration only
fname.value = tokens[0];
lname.value = tokens[1];
yourForm.appendChild(fname);
yourForm.appendChild(lname);
}
For me, the reason for having a single field is for form simplicity, which will get higher conversions.
Getting PHP to split name into firstname and lastname, then getting PHP to resubmit the form to another server might be a bit tricky...

Categories

Resources