mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 13:27:31 -08:00
feat(core): Add migration to add property userActivated to user settings (no-changelog) (#5940)
* Add userActivated migration * Fix migration logic * Remove duplication when retrieving the activated users * Fix bug updating settings in mysql * Make userSettings type conform with naming convention * Disable naming convention rule only in IDatabaseCollections interface * Fix down method in Postgres migration * Reset '{}' to NULL when reversing migration
This commit is contained in:
parent
ab12d3e327
commit
8a38624cbc
|
@ -1,4 +1,3 @@
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
import type { Application } from 'express';
|
import type { Application } from 'express';
|
||||||
import type {
|
import type {
|
||||||
ExecutionError,
|
ExecutionError,
|
||||||
|
@ -82,6 +81,7 @@ export interface ICredentialsOverwrite {
|
||||||
[key: string]: ICredentialDataDecryptedObject;
|
[key: string]: ICredentialDataDecryptedObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
export interface IDatabaseCollections {
|
export interface IDatabaseCollections {
|
||||||
AuthIdentity: AuthIdentityRepository;
|
AuthIdentity: AuthIdentityRepository;
|
||||||
AuthProviderSyncHistory: AuthProviderSyncHistoryRepository;
|
AuthProviderSyncHistory: AuthProviderSyncHistoryRepository;
|
||||||
|
@ -103,6 +103,7 @@ export interface IDatabaseCollections {
|
||||||
WorkflowStatistics: WorkflowStatisticsRepository;
|
WorkflowStatistics: WorkflowStatisticsRepository;
|
||||||
WorkflowTagMapping: WorkflowTagMappingRepository;
|
WorkflowTagMapping: WorkflowTagMappingRepository;
|
||||||
}
|
}
|
||||||
|
/* eslint-enable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// tags
|
// tags
|
||||||
|
@ -789,3 +790,5 @@ export interface N8nApp {
|
||||||
externalHooks: IExternalHooksClass;
|
externalHooks: IExternalHooksClass;
|
||||||
activeWorkflowRunner: ActiveWorkflowRunner;
|
activeWorkflowRunner: ActiveWorkflowRunner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UserSettings = Pick<User, 'id' | 'settings'>;
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
|
||||||
|
import type { UserSettings } from '@/Interfaces';
|
||||||
|
|
||||||
|
export class AddUserActivatedProperty1681134145996 implements MigrationInterface {
|
||||||
|
name = 'AddUserActivatedProperty1681134145996';
|
||||||
|
|
||||||
|
async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
logMigrationStart(this.name);
|
||||||
|
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
|
||||||
|
const activatedUsers: UserSettings[] = await queryRunner.query(
|
||||||
|
`SELECT DISTINCT sw.userId AS id,
|
||||||
|
JSON_SET(COALESCE(u.settings, '{}'), '$.userActivated', true) AS settings
|
||||||
|
FROM ${tablePrefix}workflow_statistics AS ws
|
||||||
|
JOIN ${tablePrefix}shared_workflow as sw
|
||||||
|
ON ws.workflowId = sw.workflowId
|
||||||
|
JOIN ${tablePrefix}role AS r
|
||||||
|
ON r.id = sw.roleId
|
||||||
|
JOIN ${tablePrefix}user AS u
|
||||||
|
ON u.id = sw.userId
|
||||||
|
WHERE ws.name = 'production_success'
|
||||||
|
AND r.name = 'owner'
|
||||||
|
AND r.scope = 'workflow'`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedUsers = activatedUsers.map((user) =>
|
||||||
|
queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = '${JSON.stringify(user.settings)}' WHERE id = '${
|
||||||
|
user.id
|
||||||
|
}' `,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(updatedUsers);
|
||||||
|
|
||||||
|
if (!activatedUsers.length) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', false)`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const activatedUserIds = activatedUsers.map((user) => `'${user.id}'`).join(',');
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', false) WHERE id NOT IN (${activatedUserIds})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logMigrationEnd(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_REMOVE(settings, '$.userActivated')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`UPDATE ${tablePrefix}user SET settings = NULL WHERE settings = '{}'`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ import { MigrateExecutionStatus1676996103000 } from './1676996103000-MigrateExec
|
||||||
import { UpdateRunningExecutionStatus1677236788851 } from './1677236788851-UpdateRunningExecutionStatus';
|
import { UpdateRunningExecutionStatus1677236788851 } from './1677236788851-UpdateRunningExecutionStatus';
|
||||||
import { CreateExecutionMetadataTable1679416281779 } from './1679416281779-CreateExecutionMetadataTable';
|
import { CreateExecutionMetadataTable1679416281779 } from './1679416281779-CreateExecutionMetadataTable';
|
||||||
import { CreateVariables1677501636753 } from './1677501636753-CreateVariables';
|
import { CreateVariables1677501636753 } from './1677501636753-CreateVariables';
|
||||||
|
import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserActivatedProperty';
|
||||||
|
|
||||||
export const mysqlMigrations = [
|
export const mysqlMigrations = [
|
||||||
InitialMigration1588157391238,
|
InitialMigration1588157391238,
|
||||||
|
@ -76,4 +77,5 @@ export const mysqlMigrations = [
|
||||||
UpdateRunningExecutionStatus1677236788851,
|
UpdateRunningExecutionStatus1677236788851,
|
||||||
CreateExecutionMetadataTable1679416281779,
|
CreateExecutionMetadataTable1679416281779,
|
||||||
CreateVariables1677501636753,
|
CreateVariables1677501636753,
|
||||||
|
AddUserActivatedProperty1681134145996,
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
|
||||||
|
import type { UserSettings } from '@/Interfaces';
|
||||||
|
|
||||||
|
export class AddUserActivatedProperty1681134145996 implements MigrationInterface {
|
||||||
|
name = 'AddUserActivatedProperty1681134145996';
|
||||||
|
|
||||||
|
async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
logMigrationStart(this.name);
|
||||||
|
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
|
||||||
|
const activatedUsers: UserSettings[] = await queryRunner.query(
|
||||||
|
`SELECT DISTINCT sw."userId" AS id,
|
||||||
|
JSONB_SET(COALESCE(u.settings::jsonb, '{}'), '{userActivated}', 'true', true) as settings
|
||||||
|
FROM ${tablePrefix}workflow_statistics ws
|
||||||
|
JOIN ${tablePrefix}shared_workflow sw
|
||||||
|
ON ws."workflowId" = sw."workflowId"
|
||||||
|
JOIN ${tablePrefix}role r
|
||||||
|
ON r.id = sw."roleId"
|
||||||
|
JOIN "${tablePrefix}user" u
|
||||||
|
ON u.id = sw."userId"
|
||||||
|
WHERE ws.name = 'production_success'
|
||||||
|
AND r.name = 'owner'
|
||||||
|
AND r.scope = 'workflow'`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedUsers = activatedUsers.map((user) =>
|
||||||
|
queryRunner.query(
|
||||||
|
`UPDATE "${tablePrefix}user" SET settings = '${JSON.stringify(
|
||||||
|
user.settings,
|
||||||
|
)}' WHERE id = '${user.id}' `,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(updatedUsers);
|
||||||
|
|
||||||
|
if (!activatedUsers.length) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE "${tablePrefix}user" SET settings = JSONB_SET(COALESCE(settings::jsonb, '{}'), '{userActivated}', 'false', true)`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const activatedUserIds = activatedUsers.map((user) => `'${user.id}'`).join(',');
|
||||||
|
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE "${tablePrefix}user" SET settings = JSONB_SET(COALESCE(settings::jsonb, '{}'), '{userActivated}', 'false', true) WHERE id NOT IN (${activatedUserIds})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logMigrationEnd(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE "${tablePrefix}user" SET settings = settings::jsonb - 'userActivated'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE "${tablePrefix}user" SET settings = NULL WHERE settings::jsonb = '{}'::jsonb`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ import { MigrateExecutionStatus1676996103000 } from './1676996103000-MigrateExec
|
||||||
import { UpdateRunningExecutionStatus1677236854063 } from './1677236854063-UpdateRunningExecutionStatus';
|
import { UpdateRunningExecutionStatus1677236854063 } from './1677236854063-UpdateRunningExecutionStatus';
|
||||||
import { CreateExecutionMetadataTable1679416281778 } from './1679416281778-CreateExecutionMetadataTable';
|
import { CreateExecutionMetadataTable1679416281778 } from './1679416281778-CreateExecutionMetadataTable';
|
||||||
import { CreateVariables1677501636754 } from './1677501636754-CreateVariables';
|
import { CreateVariables1677501636754 } from './1677501636754-CreateVariables';
|
||||||
|
import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserActivatedProperty';
|
||||||
|
|
||||||
export const postgresMigrations = [
|
export const postgresMigrations = [
|
||||||
InitialMigration1587669153312,
|
InitialMigration1587669153312,
|
||||||
|
@ -72,4 +73,5 @@ export const postgresMigrations = [
|
||||||
UpdateRunningExecutionStatus1677236854063,
|
UpdateRunningExecutionStatus1677236854063,
|
||||||
CreateExecutionMetadataTable1679416281778,
|
CreateExecutionMetadataTable1679416281778,
|
||||||
CreateVariables1677501636754,
|
CreateVariables1677501636754,
|
||||||
|
AddUserActivatedProperty1681134145996,
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
import { getTablePrefix, logMigrationEnd, logMigrationStart } from '@db/utils/migrationHelpers';
|
||||||
|
import type { UserSettings } from '@/Interfaces';
|
||||||
|
|
||||||
|
export class AddUserActivatedProperty1681134145996 implements MigrationInterface {
|
||||||
|
name = 'AddUserActivatedProperty1681134145996';
|
||||||
|
|
||||||
|
async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
logMigrationStart(this.name);
|
||||||
|
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
|
||||||
|
const activatedUsers: UserSettings[] = await queryRunner.query(
|
||||||
|
`SELECT DISTINCT sw.userId AS id,
|
||||||
|
JSON_SET(COALESCE(u.settings, '{}'), '$.userActivated', JSON('true')) AS settings
|
||||||
|
FROM ${tablePrefix}workflow_statistics AS ws
|
||||||
|
JOIN ${tablePrefix}shared_workflow AS sw
|
||||||
|
ON ws.workflowId = sw.workflowId
|
||||||
|
JOIN ${tablePrefix}role AS r
|
||||||
|
ON r.id = sw.roleId
|
||||||
|
JOIN ${tablePrefix}user AS u
|
||||||
|
ON u.id = sw.userId
|
||||||
|
WHERE ws.name = 'production_success'
|
||||||
|
AND r.name = 'owner'
|
||||||
|
AND r.scope = "workflow"`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedUsers = activatedUsers.map((user) =>
|
||||||
|
queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = '${user.settings}' WHERE id = '${user.id}' `,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(updatedUsers);
|
||||||
|
|
||||||
|
if (!activatedUsers.length) {
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', JSON('false'))`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const activatedUserIds = activatedUsers.map((user) => `'${user.id}'`).join(',');
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_SET(COALESCE(settings, '{}'), '$.userActivated', JSON('false')) WHERE id NOT IN (${activatedUserIds})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logMigrationEnd(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
const tablePrefix = getTablePrefix();
|
||||||
|
await queryRunner.query(
|
||||||
|
`UPDATE ${tablePrefix}user SET settings = JSON_REMOVE(settings, '$.userActivated')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`UPDATE ${tablePrefix}user SET settings = NULL WHERE settings = '{}'`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ import { MigrateExecutionStatus1676996103000 } from './1676996103000-MigrateExec
|
||||||
import { UpdateRunningExecutionStatus1677237073720 } from './1677237073720-UpdateRunningExecutionStatus';
|
import { UpdateRunningExecutionStatus1677237073720 } from './1677237073720-UpdateRunningExecutionStatus';
|
||||||
import { CreateExecutionMetadataTable1679416281777 } from './1679416281777-CreateExecutionMetadataTable';
|
import { CreateExecutionMetadataTable1679416281777 } from './1679416281777-CreateExecutionMetadataTable';
|
||||||
import { CreateVariables1677501636752 } from './1677501636752-CreateVariables';
|
import { CreateVariables1677501636752 } from './1677501636752-CreateVariables';
|
||||||
|
import { AddUserActivatedProperty1681134145996 } from './1681134145996-AddUserActivatedProperty';
|
||||||
|
|
||||||
const sqliteMigrations = [
|
const sqliteMigrations = [
|
||||||
InitialMigration1588102412422,
|
InitialMigration1588102412422,
|
||||||
|
@ -70,6 +71,7 @@ const sqliteMigrations = [
|
||||||
UpdateRunningExecutionStatus1677237073720,
|
UpdateRunningExecutionStatus1677237073720,
|
||||||
CreateVariables1677501636752,
|
CreateVariables1677501636752,
|
||||||
CreateExecutionMetadataTable1679416281777,
|
CreateExecutionMetadataTable1679416281777,
|
||||||
|
AddUserActivatedProperty1681134145996,
|
||||||
];
|
];
|
||||||
|
|
||||||
export { sqliteMigrations };
|
export { sqliteMigrations };
|
||||||
|
|
Loading…
Reference in a new issue