fix: Emails should be stored and processed in lowercase (#1109)
This commit is contained in:
@ -20,7 +20,7 @@ router.post('email', async ctx => {
|
|||||||
ctx.assertEmail(email, 'email is required');
|
ctx.assertEmail(email, 'email is required');
|
||||||
|
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
where: { email },
|
where: { email: email.toLowerCase() },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
@ -17,14 +17,22 @@ export default async function userInviter({
|
|||||||
}): Promise<{ sent: Invite[] }> {
|
}): Promise<{ sent: Invite[] }> {
|
||||||
const team = await Team.findByPk(user.teamId);
|
const team = await Team.findByPk(user.teamId);
|
||||||
|
|
||||||
// filter out empties, duplicates and obvious non-emails
|
// filter out empties and obvious non-emails
|
||||||
const compactedInvites = uniqBy(
|
const compactedInvites = invites.filter(
|
||||||
invites.filter(invite => !!invite.email.trim() && invite.email.match('@')),
|
invite => !!invite.email.trim() && invite.email.match('@')
|
||||||
|
);
|
||||||
|
|
||||||
|
// normalize to lowercase and remove duplicates
|
||||||
|
const normalizedInvites = uniqBy(
|
||||||
|
compactedInvites.map(invite => ({
|
||||||
|
...invite,
|
||||||
|
email: invite.email.toLowerCase(),
|
||||||
|
})),
|
||||||
'email'
|
'email'
|
||||||
);
|
);
|
||||||
const emails = compactedInvites.map(invite => invite.email);
|
|
||||||
|
|
||||||
// filter out existing users
|
// filter out any existing users in the system
|
||||||
|
const emails = normalizedInvites.map(invite => invite.email);
|
||||||
const existingUsers = await User.findAll({
|
const existingUsers = await User.findAll({
|
||||||
where: {
|
where: {
|
||||||
teamId: user.teamId,
|
teamId: user.teamId,
|
||||||
@ -32,11 +40,11 @@ export default async function userInviter({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const existingEmails = existingUsers.map(user => user.email);
|
const existingEmails = existingUsers.map(user => user.email);
|
||||||
const filteredInvites = compactedInvites.filter(
|
const filteredInvites = normalizedInvites.filter(
|
||||||
invite => !existingEmails.includes(invite.email)
|
invite => !existingEmails.includes(invite.email)
|
||||||
);
|
);
|
||||||
|
|
||||||
// send and record invites
|
// send and record remaining invites
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
filteredInvites.map(async invite => {
|
filteredInvites.map(async invite => {
|
||||||
const transaction = await sequelize.transaction();
|
const transaction = await sequelize.transaction();
|
||||||
|
@ -43,7 +43,7 @@ describe('userInviter', async () => {
|
|||||||
const response = await userInviter({
|
const response = await userInviter({
|
||||||
invites: [
|
invites: [
|
||||||
{ email: 'the@same.com', name: 'Test' },
|
{ email: 'the@same.com', name: 'Test' },
|
||||||
{ email: 'the@same.com', name: 'Test' },
|
{ email: 'the@SAME.COM', name: 'Test' },
|
||||||
],
|
],
|
||||||
user,
|
user,
|
||||||
ip,
|
ip,
|
||||||
|
Reference in New Issue
Block a user