fix(core): Fix AddMfaColumns migration for sqlite (no-changelog) (#7006)

When ever we have migrations that use `.addColumn` or `.dropColumn`,
typeorm recreates tables for sqlite. so, we need to disable foreign key
enforcement for sqlite, or else data in some tables can get deleted
because of `ON DELETE CASCADE`

[This has happened in the
past](https://github.com/n8n-io/n8n/pull/6739), and we should really
come up with a way to prevent this from happening again.

---------

Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-08-24 15:31:37 +02:00
committed by GitHub
parent 2b7ba6fdf1
commit 92d4befea6
6 changed files with 20 additions and 21 deletions

View File

@@ -3,6 +3,7 @@ import { INSTANCE_OWNER, BACKEND_BASE_URL } from '../constants';
import { SigninPage } from '../pages'; import { SigninPage } from '../pages';
import { PersonalSettingsPage } from '../pages/settings-personal'; import { PersonalSettingsPage } from '../pages/settings-personal';
import { MfaLoginPage } from '../pages/mfa-login'; import { MfaLoginPage } from '../pages/mfa-login';
import generateOTPToken from 'cypress-otp';
const MFA_SECRET = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD'; const MFA_SECRET = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
@@ -41,10 +42,9 @@ describe('Two-factor authentication', () => {
signinPage.actions.loginWithEmailAndPassword(email, password); signinPage.actions.loginWithEmailAndPassword(email, password);
personalSettingsPage.actions.enableMfa(); personalSettingsPage.actions.enableMfa();
mainSidebar.actions.signout(); mainSidebar.actions.signout();
cy.generateToken(user.mfaSecret).then((token) => { const token = generateOTPToken(user.mfaSecret)
mfaLoginPage.actions.loginWithMfaToken(email, password, token); mfaLoginPage.actions.loginWithMfaToken(email, password, token);
mainSidebar.actions.signout(); mainSidebar.actions.signout();
});
}); });
it('Should be able to login with recovery code', () => { it('Should be able to login with recovery code', () => {
@@ -61,10 +61,9 @@ describe('Two-factor authentication', () => {
signinPage.actions.loginWithEmailAndPassword(email, password); signinPage.actions.loginWithEmailAndPassword(email, password);
personalSettingsPage.actions.enableMfa(); personalSettingsPage.actions.enableMfa();
mainSidebar.actions.signout(); mainSidebar.actions.signout();
cy.generateToken(user.mfaSecret).then((token) => { const token = generateOTPToken(user.mfaSecret)
mfaLoginPage.actions.loginWithMfaToken(email, password, token); mfaLoginPage.actions.loginWithMfaToken(email, password, token);
personalSettingsPage.actions.disableMfa(); personalSettingsPage.actions.disableMfa();
mainSidebar.actions.signout(); mainSidebar.actions.signout();
});
}); });
}); });

View File

@@ -1,6 +1,7 @@
import { ChangePasswordModal } from './modals/change-password-modal'; import { ChangePasswordModal } from './modals/change-password-modal';
import { MfaSetupModal } from './modals/mfa-setup-modal'; import { MfaSetupModal } from './modals/mfa-setup-modal';
import { BasePage } from './base'; import { BasePage } from './base';
import generateOTPToken from 'cypress-otp';
const changePasswordModal = new ChangePasswordModal(); const changePasswordModal = new ChangePasswordModal();
const mfaSetupModal = new MfaSetupModal(); const mfaSetupModal = new MfaSetupModal();
@@ -61,11 +62,11 @@ export class PersonalSettingsPage extends BasePage {
this.getters.enableMfaButton().click(); this.getters.enableMfaButton().click();
mfaSetupModal.getters.copySecretToClipboardButton().realClick(); mfaSetupModal.getters.copySecretToClipboardButton().realClick();
cy.readClipboard().then((secret) => { cy.readClipboard().then((secret) => {
cy.generateToken(secret).then((token) => { const token = generateOTPToken(secret)
mfaSetupModal.getters.tokenInput().type(token);
mfaSetupModal.getters.downloadRecoveryCodesButton().click(); mfaSetupModal.getters.tokenInput().type(token);
mfaSetupModal.getters.saveButton().click(); mfaSetupModal.getters.downloadRecoveryCodesButton().click();
}); mfaSetupModal.getters.saveButton().click();
}); });
}, },
disableMfa: () => { disableMfa: () => {

View File

@@ -1,7 +1,6 @@
import 'cypress-real-events'; import 'cypress-real-events';
import { WorkflowPage } from '../pages'; import { WorkflowPage } from '../pages';
import { BACKEND_BASE_URL, N8N_AUTH_COOKIE } from '../constants'; import { BACKEND_BASE_URL, N8N_AUTH_COOKIE } from '../constants';
import generateOTPToken from 'cypress-otp';
Cypress.Commands.add('getByTestId', (selector, ...args) => { Cypress.Commands.add('getByTestId', (selector, ...args) => {
return cy.get(`[data-test-id="${selector}"]`, ...args); return cy.get(`[data-test-id="${selector}"]`, ...args);
@@ -162,7 +161,3 @@ Cypress.Commands.add('draganddrop', (draggableSelector, droppableSelector) => {
} }
}); });
}); });
Cypress.Commands.add('generateToken', (secret: string) => {
return generateOTPToken(secret);
});

View File

@@ -37,7 +37,6 @@ declare global {
options?: { abs?: boolean; index?: number; realMouse?: boolean }, options?: { abs?: boolean; index?: number; realMouse?: boolean },
): void; ): void;
draganddrop(draggableSelector: string, droppableSelector: string): void; draganddrop(draggableSelector: string, droppableSelector: string): void;
generateToken(mfaSecret: string): Chainable<string>;
} }
} }
} }

View File

@@ -0,0 +1,5 @@
import { AddMfaColumns1690000000030 as BaseMigration } from '../common/1690000000040-AddMfaColumns';
export class AddMfaColumns1690000000030 extends BaseMigration {
transaction = false as const;
}

View File

@@ -41,7 +41,7 @@ import { RemoveSkipOwnerSetup1681134145997 } from './1681134145997-RemoveSkipOwn
import { FixMissingIndicesFromStringIdMigration1690000000020 } from './1690000000020-FixMissingIndicesFromStringIdMigration'; import { FixMissingIndicesFromStringIdMigration1690000000020 } from './1690000000020-FixMissingIndicesFromStringIdMigration';
import { RemoveResetPasswordColumns1690000000030 } from './1690000000030-RemoveResetPasswordColumns'; import { RemoveResetPasswordColumns1690000000030 } from './1690000000030-RemoveResetPasswordColumns';
import { CreateWorkflowNameIndex1691088862123 } from '../common/1691088862123-CreateWorkflowNameIndex'; import { CreateWorkflowNameIndex1691088862123 } from '../common/1691088862123-CreateWorkflowNameIndex';
import { AddMfaColumns1690000000030 } from './../common/1690000000040-AddMfaColumns'; import { AddMfaColumns1690000000030 } from './1690000000040-AddMfaColumns';
const sqliteMigrations: Migration[] = [ const sqliteMigrations: Migration[] = [
InitialMigration1588102412422, InitialMigration1588102412422,