1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-09-19 17:07:18 +03:00

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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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 { PersonalSettingsPage } from '../pages/settings-personal';
import { MfaLoginPage } from '../pages/mfa-login';
import generateOTPToken from 'cypress-otp';
const MFA_SECRET = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
@ -41,10 +42,9 @@ describe('Two-factor authentication', () => {
signinPage.actions.loginWithEmailAndPassword(email, password);
personalSettingsPage.actions.enableMfa();
mainSidebar.actions.signout();
cy.generateToken(user.mfaSecret).then((token) => {
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
mainSidebar.actions.signout();
});
const token = generateOTPToken(user.mfaSecret)
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
mainSidebar.actions.signout();
});
it('Should be able to login with recovery code', () => {
@ -61,10 +61,9 @@ describe('Two-factor authentication', () => {
signinPage.actions.loginWithEmailAndPassword(email, password);
personalSettingsPage.actions.enableMfa();
mainSidebar.actions.signout();
cy.generateToken(user.mfaSecret).then((token) => {
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
personalSettingsPage.actions.disableMfa();
mainSidebar.actions.signout();
});
const token = generateOTPToken(user.mfaSecret)
mfaLoginPage.actions.loginWithMfaToken(email, password, token);
personalSettingsPage.actions.disableMfa();
mainSidebar.actions.signout();
});
});

View File

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

View File

@ -1,7 +1,6 @@
import 'cypress-real-events';
import { WorkflowPage } from '../pages';
import { BACKEND_BASE_URL, N8N_AUTH_COOKIE } from '../constants';
import generateOTPToken from 'cypress-otp';
Cypress.Commands.add('getByTestId', (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 },
): 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 { RemoveResetPasswordColumns1690000000030 } from './1690000000030-RemoveResetPasswordColumns';
import { CreateWorkflowNameIndex1691088862123 } from '../common/1691088862123-CreateWorkflowNameIndex';
import { AddMfaColumns1690000000030 } from './../common/1690000000040-AddMfaColumns';
import { AddMfaColumns1690000000030 } from './1690000000040-AddMfaColumns';
const sqliteMigrations: Migration[] = [
InitialMigration1588102412422,