fix(core): Make email for UM case insensitive (#3078)
* 🚧 lowercasing email * ✅ add tests for case insensitive email * 🐘 add migration to lowercase email * 🚚 rename migration * 🐛 fix package.lock * 🐛 fix double import * 📋 add todo
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
} from './Interfaces';
|
||||
import { NodeMailer } from './NodeMailer';
|
||||
|
||||
// TODO: make function fully async (remove sync functions)
|
||||
async function getTemplate(configKeyName: string, defaultFilename: string) {
|
||||
const templateOverride = (await GenericHelpers.getConfigValue(
|
||||
`userManagement.emails.templates.${configKeyName}`,
|
||||
|
||||
@@ -104,7 +104,7 @@ export function usersNamespace(this: N8nApp): void {
|
||||
400,
|
||||
);
|
||||
}
|
||||
createUsers[invite.email] = null;
|
||||
createUsers[invite.email.toLowerCase()] = null;
|
||||
});
|
||||
|
||||
const role = await Db.collections.Role.findOne({ scope: 'global', name: 'member' });
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
BeforeInsert,
|
||||
} from 'typeorm';
|
||||
import { IsEmail, IsString, Length } from 'class-validator';
|
||||
import * as config from '../../../config';
|
||||
@@ -20,7 +21,7 @@ import { Role } from './Role';
|
||||
import { SharedWorkflow } from './SharedWorkflow';
|
||||
import { SharedCredentials } from './SharedCredentials';
|
||||
import { NoXss } from '../utils/customValidators';
|
||||
import { answersFormatter } from '../utils/transformers';
|
||||
import { answersFormatter, lowerCaser } from '../utils/transformers';
|
||||
|
||||
export const MIN_PASSWORD_LENGTH = 8;
|
||||
|
||||
@@ -62,7 +63,11 @@ export class User {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ length: 254, nullable: true })
|
||||
@Column({
|
||||
length: 254,
|
||||
nullable: true,
|
||||
transformer: lowerCaser,
|
||||
})
|
||||
@Index({ unique: true })
|
||||
@IsEmail()
|
||||
email: string;
|
||||
@@ -119,8 +124,10 @@ export class User {
|
||||
})
|
||||
updatedAt: Date;
|
||||
|
||||
@BeforeInsert()
|
||||
@BeforeUpdate()
|
||||
setUpdateDate(): void {
|
||||
preUpsertHook(): void {
|
||||
this.email = this.email?.toLowerCase();
|
||||
this.updatedAt = new Date();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import config = require('../../../../config');
|
||||
|
||||
export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
|
||||
name = 'LowerCaseUserEmail1648740597343';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
const tablePrefix = config.get('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(`
|
||||
UPDATE ${tablePrefix}user
|
||||
SET email = LOWER(email);
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { AddWaitColumnId1626183952959 } from './1626183952959-AddWaitColumn';
|
||||
import { UpdateWorkflowCredentials1630451444017 } from './1630451444017-UpdateWorkflowCredentials';
|
||||
import { AddExecutionEntityIndexes1644424784709 } from './1644424784709-AddExecutionEntityIndexes';
|
||||
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
|
||||
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';
|
||||
|
||||
export const mysqlMigrations = [
|
||||
InitialMigration1588157391238,
|
||||
@@ -28,4 +29,5 @@ export const mysqlMigrations = [
|
||||
UpdateWorkflowCredentials1630451444017,
|
||||
AddExecutionEntityIndexes1644424784709,
|
||||
CreateUserManagement1646992772331,
|
||||
LowerCaseUserEmail1648740597343,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import config = require('../../../../config');
|
||||
|
||||
export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
|
||||
name = 'LowerCaseUserEmail1648740597343';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
let tablePrefix = config.get('database.tablePrefix');
|
||||
const schema = config.get('database.postgresdb.schema');
|
||||
if (schema) {
|
||||
tablePrefix = schema + '.' + tablePrefix;
|
||||
}
|
||||
|
||||
await queryRunner.query(`
|
||||
UPDATE ${tablePrefix}user
|
||||
SET email = LOWER(email);
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import { UpdateWorkflowCredentials1630419189837 } from './1630419189837-UpdateWo
|
||||
import { AddExecutionEntityIndexes1644422880309 } from './1644422880309-AddExecutionEntityIndexes';
|
||||
import { IncreaseTypeVarcharLimit1646834195327 } from './1646834195327-IncreaseTypeVarcharLimit';
|
||||
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
|
||||
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';
|
||||
|
||||
export const postgresMigrations = [
|
||||
InitialMigration1587669153312,
|
||||
@@ -24,4 +25,5 @@ export const postgresMigrations = [
|
||||
AddExecutionEntityIndexes1644422880309,
|
||||
IncreaseTypeVarcharLimit1646834195327,
|
||||
CreateUserManagement1646992772331,
|
||||
LowerCaseUserEmail1648740597343,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import config = require('../../../../config');
|
||||
import { logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';
|
||||
|
||||
export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
|
||||
name = 'LowerCaseUserEmail1648740597343';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
logMigrationStart(this.name);
|
||||
|
||||
const tablePrefix = config.get('database.tablePrefix');
|
||||
|
||||
await queryRunner.query(`
|
||||
UPDATE "${tablePrefix}user"
|
||||
SET email = LOWER(email);
|
||||
`);
|
||||
|
||||
logMigrationEnd(this.name);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { AddWaitColumn1621707690587 } from './1621707690587-AddWaitColumn';
|
||||
import { UpdateWorkflowCredentials1630330987096 } from './1630330987096-UpdateWorkflowCredentials';
|
||||
import { AddExecutionEntityIndexes1644421939510 } from './1644421939510-AddExecutionEntityIndexes';
|
||||
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
|
||||
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';
|
||||
|
||||
const sqliteMigrations = [
|
||||
InitialMigration1588102412422,
|
||||
@@ -24,6 +25,7 @@ const sqliteMigrations = [
|
||||
UpdateWorkflowCredentials1630330987096,
|
||||
AddExecutionEntityIndexes1644421939510,
|
||||
CreateUserManagement1646992772331,
|
||||
LowerCaseUserEmail1648740597343,
|
||||
];
|
||||
|
||||
export { sqliteMigrations };
|
||||
|
||||
@@ -2,8 +2,13 @@
|
||||
import { IPersonalizationSurveyAnswers } from '../../Interfaces';
|
||||
|
||||
export const idStringifier = {
|
||||
from: (value: number): string | number => (value ? value.toString() : value),
|
||||
to: (value: string): number | string => (value ? Number(value) : value),
|
||||
from: (value: number): string | number => (typeof value === 'number' ? value.toString() : value),
|
||||
to: (value: string): number | string => (typeof value === 'string' ? Number(value) : value),
|
||||
};
|
||||
|
||||
export const lowerCaser = {
|
||||
from: (value: string): string => value,
|
||||
to: (value: string): string => (typeof value === 'string' ? value.toLowerCase() : value),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user