mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
ci(core): Reduce memory usage in tests (part-2) (no-changelog) (#7671)
This also gets rid of `Db.collection`, which was another source of circular dependencies.
This commit is contained in:
parent
37dd658dc5
commit
000e76e3b4
3
.github/workflows/units-tests-reusable.yml
vendored
3
.github/workflows/units-tests-reusable.yml
vendored
|
@ -60,6 +60,9 @@ jobs:
|
|||
- name: Test Backend
|
||||
run: pnpm test:backend
|
||||
|
||||
- name: Test Nodes
|
||||
run: pnpm test:nodes
|
||||
|
||||
- name: Test Frontend
|
||||
run: pnpm test:frontend
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
"start:tunnel": "./packages/cli/bin/n8n start --tunnel",
|
||||
"start:windows": "cd packages/cli/bin && n8n",
|
||||
"test": "turbo run test",
|
||||
"test:backend": "pnpm --filter=!n8n-design-system --filter=!n8n-editor-ui test",
|
||||
"test:backend": "pnpm --filter=!n8n-design-system --filter=!n8n-editor-ui --filter=!n8n-nodes-base test",
|
||||
"test:nodes": "pnpm --filter=n8n-nodes-base test",
|
||||
"test:frontend": "pnpm --filter=n8n-design-system --filter=n8n-editor-ui test",
|
||||
"watch": "turbo run watch",
|
||||
"webhook": "./packages/cli/bin/n8n webhook",
|
||||
|
|
|
@ -19,7 +19,7 @@ import type {
|
|||
IWorkflowExecutionDataProcess,
|
||||
} from '@/Interfaces';
|
||||
import { isWorkflowIdValid } from '@/utils';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
@Service()
|
||||
|
|
|
@ -33,7 +33,6 @@ import {
|
|||
|
||||
import type express from 'express';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import type {
|
||||
IResponseCallbackData,
|
||||
IWebhookManager,
|
||||
|
@ -63,7 +62,8 @@ import { webhookNotFoundErrorMessage } from './utils';
|
|||
import { In } from 'typeorm';
|
||||
import { WebhookService } from './services/webhook.service';
|
||||
import { Logger } from './Logger';
|
||||
import { WorkflowRepository } from '@/databases/repositories';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import config from '@/config';
|
||||
import type { MultiMainInstancePublisher } from './services/orchestration/main/MultiMainInstance.publisher.ee';
|
||||
|
||||
|
@ -104,6 +104,7 @@ export class ActiveWorkflowRunner implements IWebhookManager {
|
|||
private readonly nodeTypes: NodeTypes,
|
||||
private readonly webhookService: WebhookService,
|
||||
private readonly workflowRepository: WorkflowRepository,
|
||||
private readonly sharedWorkflowRepository: SharedWorkflowRepository,
|
||||
) {}
|
||||
|
||||
async init() {
|
||||
|
@ -188,7 +189,7 @@ export class ActiveWorkflowRunner implements IWebhookManager {
|
|||
});
|
||||
}
|
||||
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
const workflowData = await this.workflowRepository.findOne({
|
||||
where: { id: webhook.workflowId },
|
||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||
});
|
||||
|
@ -296,7 +297,7 @@ export class ActiveWorkflowRunner implements IWebhookManager {
|
|||
|
||||
Object.assign(where, { workflowId: In(activeIds) });
|
||||
|
||||
const sharings = await Db.collections.SharedWorkflow.find({
|
||||
const sharings = await this.sharedWorkflowRepository.find({
|
||||
select: ['workflowId'],
|
||||
where,
|
||||
});
|
||||
|
@ -416,7 +417,7 @@ export class ActiveWorkflowRunner implements IWebhookManager {
|
|||
* Clear workflow-defined webhooks from the `webhook_entity` table.
|
||||
*/
|
||||
async clearWebhooks(workflowId: string) {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
const workflowData = await this.workflowRepository.findOne({
|
||||
where: { id: workflowId },
|
||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||
});
|
||||
|
|
|
@ -43,7 +43,6 @@ import {
|
|||
ErrorReporterProxy as ErrorReporter,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import type { ICredentialsDb } from '@/Interfaces';
|
||||
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
@ -54,6 +53,8 @@ import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
|||
import { RESPONSE_ERROR_MESSAGES } from './constants';
|
||||
import { isObjectLiteral } from './utils';
|
||||
import { Logger } from '@/Logger';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
|
||||
const { OAUTH2_CREDENTIAL_TEST_SUCCEEDED, OAUTH2_CREDENTIAL_TEST_FAILED } = RESPONSE_ERROR_MESSAGES;
|
||||
|
||||
|
@ -102,6 +103,8 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
private readonly credentialTypes: CredentialTypes,
|
||||
private readonly nodeTypes: NodeTypes,
|
||||
private readonly credentialsOverwrites: CredentialsOverwrites,
|
||||
private readonly credentialsRepository: CredentialsRepository,
|
||||
private readonly sharedCredentialsRepository: SharedCredentialsRepository,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
@ -271,11 +274,13 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
|
||||
try {
|
||||
credential = userId
|
||||
? await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { credentials: { id: nodeCredential.id, type }, userId },
|
||||
}).then((shared) => shared.credentials)
|
||||
: await Db.collections.Credentials.findOneByOrFail({ id: nodeCredential.id, type });
|
||||
? await this.sharedCredentialsRepository
|
||||
.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { credentials: { id: nodeCredential.id, type }, userId },
|
||||
})
|
||||
.then((shared) => shared.credentials)
|
||||
: await this.credentialsRepository.findOneByOrFail({ id: nodeCredential.id, type });
|
||||
} catch (error) {
|
||||
throw new CredentialNotFoundError(nodeCredential.id, type);
|
||||
}
|
||||
|
@ -463,7 +468,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
type,
|
||||
};
|
||||
|
||||
await Db.collections.Credentials.update(findQuery, newCredentialsData);
|
||||
await this.credentialsRepository.update(findQuery, newCredentialsData);
|
||||
}
|
||||
|
||||
private static hasAccessToken(credentialsDecrypted: ICredentialsDecrypted) {
|
||||
|
@ -774,7 +779,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
return false;
|
||||
}
|
||||
|
||||
const credential = await Db.collections.SharedCredentials.findOne({
|
||||
const credential = await this.sharedCredentialsRepository.findOne({
|
||||
where: {
|
||||
role: {
|
||||
scope: 'credential',
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
|
||||
import { Container } from 'typedi';
|
||||
import type { DataSourceOptions as ConnectionOptions, EntityManager, LoggerOptions } from 'typeorm';
|
||||
import { DataSource as Connection } from 'typeorm';
|
||||
import type { TlsOptions } from 'tls';
|
||||
import { ErrorReporterProxy as ErrorReporter } from 'n8n-workflow';
|
||||
|
||||
import type { IDatabaseCollections } from '@/Interfaces';
|
||||
|
||||
import config from '@/config';
|
||||
|
||||
import { entities } from '@db/entities';
|
||||
|
@ -21,28 +18,6 @@ import {
|
|||
import { inTest } from '@/constants';
|
||||
import { wrapMigration } from '@db/utils/migrationHelpers';
|
||||
import type { DatabaseType, Migration } from '@db/types';
|
||||
import {
|
||||
AuthIdentityRepository,
|
||||
AuthProviderSyncHistoryRepository,
|
||||
CredentialsRepository,
|
||||
EventDestinationsRepository,
|
||||
ExecutionDataRepository,
|
||||
ExecutionMetadataRepository,
|
||||
ExecutionRepository,
|
||||
InstalledNodesRepository,
|
||||
InstalledPackagesRepository,
|
||||
RoleRepository,
|
||||
SettingsRepository,
|
||||
SharedCredentialsRepository,
|
||||
SharedWorkflowRepository,
|
||||
UserRepository,
|
||||
VariablesRepository,
|
||||
WorkflowRepository,
|
||||
WorkflowStatisticsRepository,
|
||||
WorkflowTagMappingRepository,
|
||||
} from '@db/repositories';
|
||||
|
||||
export const collections = {} as IDatabaseCollections;
|
||||
|
||||
let connection: Connection;
|
||||
|
||||
|
@ -165,32 +140,6 @@ export async function init(testConnectionOptions?: ConnectionOptions): Promise<v
|
|||
}
|
||||
|
||||
connectionState.connected = true;
|
||||
|
||||
/**
|
||||
* @important Do not add to these collections. Inject the repository as a dependency instead.
|
||||
*/
|
||||
collections.AuthIdentity = Container.get(AuthIdentityRepository);
|
||||
collections.AuthProviderSyncHistory = Container.get(AuthProviderSyncHistoryRepository);
|
||||
collections.EventDestinations = Container.get(EventDestinationsRepository);
|
||||
collections.Execution = Container.get(ExecutionRepository);
|
||||
collections.ExecutionData = Container.get(ExecutionDataRepository);
|
||||
collections.ExecutionMetadata = Container.get(ExecutionMetadataRepository);
|
||||
collections.InstalledNodes = Container.get(InstalledNodesRepository);
|
||||
collections.InstalledPackages = Container.get(InstalledPackagesRepository);
|
||||
collections.SharedCredentials = Container.get(SharedCredentialsRepository);
|
||||
collections.SharedWorkflow = Container.get(SharedWorkflowRepository);
|
||||
collections.Variables = Container.get(VariablesRepository);
|
||||
collections.WorkflowStatistics = Container.get(WorkflowStatisticsRepository);
|
||||
collections.WorkflowTagMapping = Container.get(WorkflowTagMappingRepository);
|
||||
|
||||
/**
|
||||
* @important Do not remove these collections until cloud hooks are backwards compatible.
|
||||
*/
|
||||
collections.Role = Container.get(RoleRepository);
|
||||
collections.User = Container.get(UserRepository);
|
||||
collections.Settings = Container.get(SettingsRepository);
|
||||
collections.Credentials = Container.get(CredentialsRepository);
|
||||
collections.Workflow = Container.get(WorkflowRepository);
|
||||
}
|
||||
|
||||
export async function migrate() {
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
import { Service } from 'typedi';
|
||||
import * as Db from '@/Db';
|
||||
import type {
|
||||
IExternalHooksClass,
|
||||
IExternalHooksFileData,
|
||||
IExternalHooksFunctions,
|
||||
} from '@/Interfaces';
|
||||
|
||||
import config from '@/config';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
@Service()
|
||||
export class ExternalHooks implements IExternalHooksClass {
|
||||
|
@ -16,7 +17,25 @@ export class ExternalHooks implements IExternalHooksClass {
|
|||
[key: string]: Array<() => {}>;
|
||||
} = {};
|
||||
|
||||
initDidRun = false;
|
||||
private initDidRun = false;
|
||||
|
||||
private dbCollections: IExternalHooksFunctions['dbCollections'];
|
||||
|
||||
constructor(
|
||||
userRepository: UserRepository,
|
||||
settingsRepository: SettingsRepository,
|
||||
credentialsRepository: CredentialsRepository,
|
||||
workflowRepository: WorkflowRepository,
|
||||
) {
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
this.dbCollections = {
|
||||
User: userRepository,
|
||||
Settings: settingsRepository,
|
||||
Credentials: credentialsRepository,
|
||||
Workflow: workflowRepository,
|
||||
};
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
if (this.initDidRun) {
|
||||
|
@ -83,14 +102,14 @@ export class ExternalHooks implements IExternalHooksClass {
|
|||
}
|
||||
|
||||
async run(hookName: string, hookParameters?: any[]): Promise<void> {
|
||||
const externalHookFunctions: IExternalHooksFunctions = {
|
||||
dbCollections: Db.collections,
|
||||
};
|
||||
|
||||
if (this.externalHooks[hookName] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const externalHookFunctions: IExternalHooksFunctions = {
|
||||
dbCollections: this.dbCollections,
|
||||
};
|
||||
|
||||
for (const externalHookFunction of this.externalHooks[hookName]) {
|
||||
await externalHookFunction.apply(externalHookFunctions, hookParameters);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { SettingsRepository } from '@/databases/repositories';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import type {
|
||||
ExternalSecretsSettings,
|
||||
SecretsProvider,
|
||||
|
|
|
@ -10,7 +10,6 @@ import { validate } from 'class-validator';
|
|||
import { Container } from 'typedi';
|
||||
import { Like } from 'typeorm';
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import type { ExecutionPayload, ICredentialsDb, IWorkflowDb } from '@/Interfaces';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
|
@ -18,7 +17,9 @@ import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
|||
import type { TagEntity } from '@db/entities/TagEntity';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type { UserUpdatePayload } from '@/requests';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
/**
|
||||
* Returns the base URL n8n is reachable from
|
||||
|
@ -64,8 +65,8 @@ export async function generateUniqueName(
|
|||
|
||||
const found: Array<WorkflowEntity | ICredentialsDb> =
|
||||
entityType === 'workflow'
|
||||
? await Db.collections.Workflow.find(findConditions)
|
||||
: await Db.collections.Credentials.find(findConditions);
|
||||
? await Container.get(WorkflowRepository).find(findConditions)
|
||||
: await Container.get(CredentialsRepository).find(findConditions);
|
||||
|
||||
// name is unique
|
||||
if (found.length === 0) {
|
||||
|
|
|
@ -30,7 +30,7 @@ import type { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
|||
import type { WorkflowExecute } from 'n8n-core';
|
||||
|
||||
import type PCancelable from 'p-cancelable';
|
||||
import type { FindOperator, Repository } from 'typeorm';
|
||||
import type { FindOperator } from 'typeorm';
|
||||
|
||||
import type { ChildProcess } from 'child_process';
|
||||
|
||||
|
@ -40,26 +40,10 @@ import type { Role } from '@db/entities/Role';
|
|||
import type { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||
import type { TagEntity } from '@db/entities/TagEntity';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type {
|
||||
AuthIdentityRepository,
|
||||
AuthProviderSyncHistoryRepository,
|
||||
CredentialsRepository,
|
||||
EventDestinationsRepository,
|
||||
ExecutionDataRepository,
|
||||
ExecutionMetadataRepository,
|
||||
ExecutionRepository,
|
||||
InstalledNodesRepository,
|
||||
InstalledPackagesRepository,
|
||||
RoleRepository,
|
||||
SettingsRepository,
|
||||
SharedCredentialsRepository,
|
||||
SharedWorkflowRepository,
|
||||
UserRepository,
|
||||
VariablesRepository,
|
||||
WorkflowRepository,
|
||||
WorkflowStatisticsRepository,
|
||||
WorkflowTagMappingRepository,
|
||||
} from '@db/repositories';
|
||||
import type { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import type { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import type { UserRepository } from '@db/repositories/user.repository';
|
||||
import type { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import type { LICENSE_FEATURES, LICENSE_QUOTAS } from './constants';
|
||||
import type { WorkflowWithSharingsAndCredentials } from './workflows/workflows.types';
|
||||
|
||||
|
@ -71,33 +55,6 @@ export interface ICredentialsOverwrite {
|
|||
[key: string]: ICredentialDataDecryptedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @important Do not add to these collections. Inject the repository as a dependency instead.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
export interface IDatabaseCollections extends Record<string, Repository<any>> {
|
||||
AuthIdentity: AuthIdentityRepository;
|
||||
AuthProviderSyncHistory: AuthProviderSyncHistoryRepository;
|
||||
Credentials: CredentialsRepository;
|
||||
EventDestinations: EventDestinationsRepository;
|
||||
Execution: ExecutionRepository;
|
||||
ExecutionData: ExecutionDataRepository;
|
||||
ExecutionMetadata: ExecutionMetadataRepository;
|
||||
InstalledNodes: InstalledNodesRepository;
|
||||
InstalledPackages: InstalledPackagesRepository;
|
||||
Role: RoleRepository;
|
||||
Settings: SettingsRepository;
|
||||
SharedCredentials: SharedCredentialsRepository;
|
||||
SharedWorkflow: SharedWorkflowRepository;
|
||||
User: UserRepository;
|
||||
Variables: VariablesRepository;
|
||||
Workflow: WorkflowRepository;
|
||||
WorkflowStatistics: WorkflowStatisticsRepository;
|
||||
WorkflowTagMapping: WorkflowTagMappingRepository;
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
// ----------------------------------
|
||||
// tags
|
||||
// ----------------------------------
|
||||
|
@ -285,7 +242,14 @@ export interface IExternalHooksFileData {
|
|||
}
|
||||
|
||||
export interface IExternalHooksFunctions {
|
||||
dbCollections: IDatabaseCollections;
|
||||
dbCollections: {
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
User: UserRepository;
|
||||
Settings: SettingsRepository;
|
||||
Credentials: CredentialsRepository;
|
||||
Workflow: WorkflowRepository;
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
};
|
||||
}
|
||||
|
||||
export interface IExternalHooksClass {
|
||||
|
|
|
@ -32,6 +32,10 @@ import {
|
|||
import { BadRequestError, InternalServerError } from '../ResponseHelper';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { Logger } from '@/Logger';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { AuthProviderSyncHistoryRepository } from '@db/repositories/authProviderSyncHistory.repository';
|
||||
import { AuthIdentityRepository } from '@db/repositories/authIdentity.repository';
|
||||
|
||||
/**
|
||||
* Check whether the LDAP feature is disabled in the instance
|
||||
|
@ -114,7 +118,7 @@ export const validateLdapConfigurationSchema = (
|
|||
* Retrieve the LDAP configuration (decrypted) form the database
|
||||
*/
|
||||
export const getLdapConfig = async (): Promise<LdapConfig> => {
|
||||
const configuration = await Db.collections.Settings.findOneByOrFail({
|
||||
const configuration = await Container.get(SettingsRepository).findOneByOrFail({
|
||||
key: LDAP_FEATURE_NAME,
|
||||
});
|
||||
const configurationData = jsonParse<LdapConfig>(configuration.value);
|
||||
|
@ -171,7 +175,7 @@ export const updateLdapConfig = async (ldapConfig: LdapConfig): Promise<void> =>
|
|||
}
|
||||
}
|
||||
|
||||
await Db.collections.Settings.update(
|
||||
await Container.get(SettingsRepository).update(
|
||||
{ key: LDAP_FEATURE_NAME },
|
||||
{ value: JSON.stringify(ldapConfig), loadOnStartup: true },
|
||||
);
|
||||
|
@ -284,7 +288,7 @@ export const findAndAuthenticateLdapUser = async (
|
|||
export const getAuthIdentityByLdapId = async (
|
||||
idAttributeValue: string,
|
||||
): Promise<AuthIdentity | null> => {
|
||||
return Db.collections.AuthIdentity.findOne({
|
||||
return Container.get(AuthIdentityRepository).findOne({
|
||||
relations: ['user', 'user.globalRole'],
|
||||
where: {
|
||||
providerId: idAttributeValue,
|
||||
|
@ -294,7 +298,7 @@ export const getAuthIdentityByLdapId = async (
|
|||
};
|
||||
|
||||
export const getUserByEmail = async (email: string): Promise<User | null> => {
|
||||
return Db.collections.User.findOne({
|
||||
return Container.get(UserRepository).findOne({
|
||||
where: { email },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
@ -322,7 +326,7 @@ export const mapLdapAttributesToUser = (
|
|||
* Retrieve LDAP ID of all LDAP users in the database
|
||||
*/
|
||||
export const getLdapIds = async (): Promise<string[]> => {
|
||||
const identities = await Db.collections.AuthIdentity.find({
|
||||
const identities = await Container.get(AuthIdentityRepository).find({
|
||||
select: ['providerId'],
|
||||
where: {
|
||||
providerType: 'ldap',
|
||||
|
@ -332,7 +336,7 @@ export const getLdapIds = async (): Promise<string[]> => {
|
|||
};
|
||||
|
||||
export const getLdapUsers = async (): Promise<User[]> => {
|
||||
const identities = await Db.collections.AuthIdentity.find({
|
||||
const identities = await Container.get(AuthIdentityRepository).find({
|
||||
relations: ['user'],
|
||||
where: {
|
||||
providerType: 'ldap',
|
||||
|
@ -409,7 +413,7 @@ export const processUsers = async (
|
|||
export const saveLdapSynchronization = async (
|
||||
data: Omit<AuthProviderSyncHistory, 'id' | 'providerType'>,
|
||||
): Promise<void> => {
|
||||
await Db.collections.AuthProviderSyncHistory.save({
|
||||
await Container.get(AuthProviderSyncHistoryRepository).save({
|
||||
...data,
|
||||
providerType: 'ldap',
|
||||
});
|
||||
|
@ -423,7 +427,7 @@ export const getLdapSynchronizations = async (
|
|||
perPage: number,
|
||||
): Promise<AuthProviderSyncHistory[]> => {
|
||||
const _page = Math.abs(page);
|
||||
return Db.collections.AuthProviderSyncHistory.find({
|
||||
return Container.get(AuthProviderSyncHistoryRepository).find({
|
||||
where: { providerType: 'ldap' },
|
||||
order: { id: 'DESC' },
|
||||
take: perPage,
|
||||
|
@ -450,11 +454,11 @@ export const getMappingAttributes = (ldapConfig: LdapConfig): string[] => {
|
|||
};
|
||||
|
||||
export const createLdapAuthIdentity = async (user: User, ldapId: string) => {
|
||||
return Db.collections.AuthIdentity.save(AuthIdentity.create(user, ldapId));
|
||||
return Container.get(AuthIdentityRepository).save(AuthIdentity.create(user, ldapId));
|
||||
};
|
||||
|
||||
export const createLdapUserOnLocalDb = async (role: Role, data: Partial<User>, ldapId: string) => {
|
||||
const user = await Db.collections.User.save({
|
||||
const user = await Container.get(UserRepository).save({
|
||||
password: randomPassword(),
|
||||
globalRole: role,
|
||||
...data,
|
||||
|
@ -466,10 +470,10 @@ export const createLdapUserOnLocalDb = async (role: Role, data: Partial<User>, l
|
|||
export const updateLdapUserOnLocalDb = async (identity: AuthIdentity, data: Partial<User>) => {
|
||||
const userId = identity?.user?.id;
|
||||
if (userId) {
|
||||
await Db.collections.User.update({ id: userId }, data);
|
||||
await Container.get(UserRepository).update({ id: userId }, data);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteAllLdapIdentities = async () => {
|
||||
return Db.collections.AuthIdentity.delete({ providerType: 'ldap' });
|
||||
return Container.get(AuthIdentityRepository).delete({ providerType: 'ldap' });
|
||||
};
|
||||
|
|
|
@ -4,7 +4,6 @@ import { InstanceSettings, ObjectStoreService } from 'n8n-core';
|
|||
import Container, { Service } from 'typedi';
|
||||
import { Logger } from '@/Logger';
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import {
|
||||
LICENSE_FEATURES,
|
||||
LICENSE_QUOTAS,
|
||||
|
@ -12,7 +11,8 @@ import {
|
|||
SETTINGS_LICENSE_CERT_KEY,
|
||||
UNLIMITED_LICENSE_QUOTA,
|
||||
} from './constants';
|
||||
import { WorkflowRepository } from '@/databases/repositories';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import type { BooleanLicenseFeature, N8nInstanceType, NumericLicenseFeature } from './Interfaces';
|
||||
import type { RedisServicePubSubPublisher } from './services/redis/RedisServicePubSubPublisher';
|
||||
import { RedisService } from './services/redis.service';
|
||||
|
@ -40,6 +40,8 @@ export class License {
|
|||
constructor(
|
||||
private readonly logger: Logger,
|
||||
private readonly instanceSettings: InstanceSettings,
|
||||
private readonly settingsRepository: SettingsRepository,
|
||||
private readonly workflowRepository: WorkflowRepository,
|
||||
) {}
|
||||
|
||||
async init(instanceType: N8nInstanceType = 'main') {
|
||||
|
@ -91,7 +93,7 @@ export class License {
|
|||
return [
|
||||
{
|
||||
name: 'activeWorkflows',
|
||||
value: await Container.get(WorkflowRepository).count({ where: { active: true } }),
|
||||
value: await this.workflowRepository.count({ where: { active: true } }),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -102,7 +104,7 @@ export class License {
|
|||
if (ephemeralLicense) {
|
||||
return ephemeralLicense;
|
||||
}
|
||||
const databaseSettings = await Db.collections.Settings.findOne({
|
||||
const databaseSettings = await this.settingsRepository.findOne({
|
||||
where: {
|
||||
key: SETTINGS_LICENSE_CERT_KEY,
|
||||
},
|
||||
|
@ -153,7 +155,7 @@ export class License {
|
|||
async saveCertStr(value: TLicenseBlock): Promise<void> {
|
||||
// if we have an ephemeral license, we don't want to save it to the database
|
||||
if (config.get('license.cert')) return;
|
||||
await Db.collections.Settings.upsert(
|
||||
await this.settingsRepository.upsert(
|
||||
{
|
||||
key: SETTINGS_LICENSE_CERT_KEY,
|
||||
value,
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import Container from 'typedi';
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import { MFA_FEATURE_ENABLED } from './constants';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export const isMfaFeatureEnabled = () => config.get(MFA_FEATURE_ENABLED);
|
||||
|
||||
const isMfaFeatureDisabled = () => !isMfaFeatureEnabled();
|
||||
|
||||
const getUsersWithMfaEnabled = async () =>
|
||||
Db.collections.User.count({ where: { mfaEnabled: true } });
|
||||
Container.get(UserRepository).count({ where: { mfaEnabled: true } });
|
||||
|
||||
export const handleMfaDisable = async () => {
|
||||
if (isMfaFeatureDisabled()) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import { Service } from 'typedi';
|
||||
import { Cipher } from 'n8n-core';
|
||||
import { UserRepository } from '@db/repositories';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { TOTPService } from './totp.service';
|
||||
|
||||
@Service()
|
||||
|
|
|
@ -11,11 +11,11 @@ import type { OpenAPIV3 } from 'openapi-types';
|
|||
import type { JsonObject } from 'swagger-ui-express';
|
||||
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';
|
||||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { License } from '@/License';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
async function createApiRouter(
|
||||
version: string,
|
||||
|
@ -95,7 +95,7 @@ async function createApiRouter(
|
|||
schema: OpenAPIV3.ApiKeySecurityScheme,
|
||||
): Promise<boolean> => {
|
||||
const apiKey = req.headers[schema.name.toLowerCase()] as string;
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Container.get(UserRepository).findOne({
|
||||
where: { apiKey },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
|
|
@ -10,9 +10,11 @@ import type { IDependency, IJsonSchema } from '../../../types';
|
|||
import type { CredentialRequest } from '@/requests';
|
||||
import { Container } from 'typedi';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
|
||||
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
|
||||
return Db.collections.Credentials.findOneBy({ id: credentialId });
|
||||
return Container.get(CredentialsRepository).findOneBy({ id: credentialId });
|
||||
}
|
||||
|
||||
export async function getSharedCredentials(
|
||||
|
@ -20,7 +22,7 @@ export async function getSharedCredentials(
|
|||
credentialId: string,
|
||||
relations?: string[],
|
||||
): Promise<SharedCredentials | null> {
|
||||
return Db.collections.SharedCredentials.findOne({
|
||||
return Container.get(SharedCredentialsRepository).findOne({
|
||||
where: {
|
||||
userId,
|
||||
credentialsId: credentialId,
|
||||
|
@ -83,7 +85,7 @@ export async function saveCredential(
|
|||
|
||||
export async function removeCredential(credentials: CredentialsEntity): Promise<ICredentialsDb> {
|
||||
await Container.get(ExternalHooks).run('credentials.delete', [credentials.id]);
|
||||
return Db.collections.Credentials.remove(credentials);
|
||||
return Container.get(CredentialsRepository).remove(credentials);
|
||||
}
|
||||
|
||||
export async function encryptCredential(credential: CredentialsEntity): Promise<ICredentialsDb> {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { getSharedWorkflowIds } from '../workflows/workflows.service';
|
|||
import { encodeNextCursor } from '../../shared/services/pagination.service';
|
||||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { ExecutionRepository } from '@/databases/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
|
||||
export = {
|
||||
deleteExecution: [
|
||||
|
|
|
@ -3,9 +3,8 @@ import { In, Not, Raw, LessThan } from 'typeorm';
|
|||
import { Container } from 'typedi';
|
||||
import type { ExecutionStatus } from 'n8n-workflow';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import type { IExecutionBase, IExecutionFlattedDb } from '@/Interfaces';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
|
||||
function getStatusCondition(status: ExecutionStatus) {
|
||||
const condition: Pick<FindOptionsWhere<IExecutionFlattedDb>, 'status'> = {};
|
||||
|
@ -83,7 +82,7 @@ export async function getExecutionsCount(data: {
|
|||
excludedWorkflowIds?: string[];
|
||||
}): Promise<number> {
|
||||
// TODO: Consider moving this to the repository as well
|
||||
const executions = await Db.collections.Execution.count({
|
||||
const executions = await Container.get(ExecutionRepository).count({
|
||||
where: {
|
||||
...(data.lastId && { id: LessThan(data.lastId) }),
|
||||
...(data.status && { ...getStatusCondition(data.status) }),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Container } from 'typedi';
|
||||
import { UserRepository } from '@db/repositories';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import type { User } from '@db/entities/User';
|
||||
import pick from 'lodash/pick';
|
||||
import { validate as uuidValidate } from 'uuid';
|
||||
|
|
|
@ -10,6 +10,8 @@ import type { Role } from '@db/entities/Role';
|
|||
import config from '@/config';
|
||||
import { TagService } from '@/services/tag.service';
|
||||
import Container from 'typedi';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
|
||||
function insertIf(condition: boolean, elements: string[]): string[] {
|
||||
return condition ? elements : [];
|
||||
|
@ -17,7 +19,7 @@ function insertIf(condition: boolean, elements: string[]): string[] {
|
|||
|
||||
export async function getSharedWorkflowIds(user: User): Promise<string[]> {
|
||||
const where = user.globalRole.name === 'owner' ? {} : { userId: user.id };
|
||||
const sharedWorkflows = await Db.collections.SharedWorkflow.find({
|
||||
const sharedWorkflows = await Container.get(SharedWorkflowRepository).find({
|
||||
where,
|
||||
select: ['workflowId'],
|
||||
});
|
||||
|
@ -28,7 +30,7 @@ export async function getSharedWorkflow(
|
|||
user: User,
|
||||
workflowId?: string | undefined,
|
||||
): Promise<SharedWorkflow | null> {
|
||||
return Db.collections.SharedWorkflow.findOne({
|
||||
return Container.get(SharedWorkflowRepository).findOne({
|
||||
where: {
|
||||
...(!user.isOwner && { userId: user.id }),
|
||||
...(workflowId && { workflowId }),
|
||||
|
@ -44,7 +46,7 @@ export async function getSharedWorkflows(
|
|||
workflowIds?: string[];
|
||||
},
|
||||
): Promise<SharedWorkflow[]> {
|
||||
return Db.collections.SharedWorkflow.find({
|
||||
return Container.get(SharedWorkflowRepository).find({
|
||||
where: {
|
||||
...(!user.isOwner && { userId: user.id }),
|
||||
...(options.workflowIds && { workflowId: In(options.workflowIds) }),
|
||||
|
@ -54,7 +56,7 @@ export async function getSharedWorkflows(
|
|||
}
|
||||
|
||||
export async function getWorkflowById(id: string): Promise<WorkflowEntity | null> {
|
||||
return Db.collections.Workflow.findOne({
|
||||
return Container.get(WorkflowRepository).findOne({
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
|
@ -97,28 +99,34 @@ export async function createWorkflow(
|
|||
}
|
||||
|
||||
export async function setWorkflowAsActive(workflow: WorkflowEntity): Promise<UpdateResult> {
|
||||
return Db.collections.Workflow.update(workflow.id, { active: true, updatedAt: new Date() });
|
||||
return Container.get(WorkflowRepository).update(workflow.id, {
|
||||
active: true,
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
export async function setWorkflowAsInactive(workflow: WorkflowEntity): Promise<UpdateResult> {
|
||||
return Db.collections.Workflow.update(workflow.id, { active: false, updatedAt: new Date() });
|
||||
return Container.get(WorkflowRepository).update(workflow.id, {
|
||||
active: false,
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteWorkflow(workflow: WorkflowEntity): Promise<WorkflowEntity> {
|
||||
return Db.collections.Workflow.remove(workflow);
|
||||
return Container.get(WorkflowRepository).remove(workflow);
|
||||
}
|
||||
|
||||
export async function getWorkflowsAndCount(
|
||||
options: FindManyOptions<WorkflowEntity>,
|
||||
): Promise<[WorkflowEntity[], number]> {
|
||||
return Db.collections.Workflow.findAndCount(options);
|
||||
return Container.get(WorkflowRepository).findAndCount(options);
|
||||
}
|
||||
|
||||
export async function updateWorkflow(
|
||||
workflowId: string,
|
||||
updateData: WorkflowEntity,
|
||||
): Promise<UpdateResult> {
|
||||
return Db.collections.Workflow.update(workflowId, updateData);
|
||||
return Container.get(WorkflowRepository).update(workflowId, updateData);
|
||||
}
|
||||
|
||||
export function parseTagNames(tags: string): string[] {
|
||||
|
|
|
@ -85,7 +85,6 @@ import { executionsController } from '@/executions/executions.controller';
|
|||
import { isApiEnabled, loadPublicApiVersions } from '@/PublicApi';
|
||||
import { whereClause } from '@/UserManagement/UserManagementHelper';
|
||||
import { UserManagementMailer } from '@/UserManagement/email';
|
||||
import * as Db from '@/Db';
|
||||
import type { ICredentialsOverwrite, IDiagnosticInfo, IExecutionsStopData } from '@/Interfaces';
|
||||
import { ActiveExecutions } from '@/ActiveExecutions';
|
||||
import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
||||
|
@ -119,8 +118,14 @@ import {
|
|||
} from './sso/ssoHelpers';
|
||||
import { SourceControlService } from '@/environments/sourceControl/sourceControl.service.ee';
|
||||
import { SourceControlController } from '@/environments/sourceControl/sourceControl.controller.ee';
|
||||
import { ExecutionRepository, SettingsRepository } from '@db/repositories';
|
||||
|
||||
import type { ExecutionEntity } from '@db/entities/ExecutionEntity';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
import { MfaService } from './Mfa/mfa.service';
|
||||
import { handleMfaDisable, isMfaFeatureEnabled } from './Mfa/helpers';
|
||||
import type { FrontendService } from './services/frontend.service';
|
||||
|
@ -236,18 +241,19 @@ export class Server extends AbstractServer {
|
|||
void this.loadNodesAndCredentials.setupHotReload();
|
||||
}
|
||||
|
||||
void Db.collections.Workflow.findOne({
|
||||
select: ['createdAt'],
|
||||
order: { createdAt: 'ASC' },
|
||||
where: {},
|
||||
}).then(async (workflow) =>
|
||||
Container.get(InternalHooks).onServerStarted(diagnosticInfo, workflow?.createdAt),
|
||||
);
|
||||
void Container.get(WorkflowRepository)
|
||||
.findOne({
|
||||
select: ['createdAt'],
|
||||
order: { createdAt: 'ASC' },
|
||||
where: {},
|
||||
})
|
||||
.then(async (workflow) =>
|
||||
Container.get(InternalHooks).onServerStarted(diagnosticInfo, workflow?.createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
private async registerControllers(ignoredEndpoints: Readonly<string[]>) {
|
||||
const { app, externalHooks, activeWorkflowRunner, nodeTypes, logger } = this;
|
||||
const repositories = Db.collections;
|
||||
setupAuthMiddlewares(app, ignoredEndpoints, this.restEndpoint);
|
||||
|
||||
const internalHooks = Container.get(InternalHooks);
|
||||
|
@ -281,8 +287,8 @@ export class Server extends AbstractServer {
|
|||
logger,
|
||||
externalHooks,
|
||||
internalHooks,
|
||||
repositories.SharedCredentials,
|
||||
repositories.SharedWorkflow,
|
||||
Container.get(SharedCredentialsRepository),
|
||||
Container.get(SharedWorkflowRepository),
|
||||
activeWorkflowRunner,
|
||||
mailer,
|
||||
jwtService,
|
||||
|
@ -623,7 +629,7 @@ export class Server extends AbstractServer {
|
|||
ResponseHelper.send(async (req: WorkflowRequest.GetAllActivationErrors) => {
|
||||
const { id: workflowId } = req.params;
|
||||
|
||||
const shared = await Db.collections.SharedWorkflow.findOne({
|
||||
const shared = await Container.get(SharedWorkflowRepository).findOne({
|
||||
relations: ['workflow'],
|
||||
where: whereClause({
|
||||
user: req.user,
|
||||
|
|
|
@ -2,13 +2,15 @@ import type { INode, Workflow } from 'n8n-workflow';
|
|||
import { NodeOperationError, SubworkflowOperationError } from 'n8n-workflow';
|
||||
import type { FindOptionsWhere } from 'typeorm';
|
||||
import { In } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import config from '@/config';
|
||||
import type { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||
import { isSharingEnabled } from './UserManagementHelper';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import Container from 'typedi';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
|
||||
export class PermissionChecker {
|
||||
/**
|
||||
|
@ -25,7 +27,7 @@ export class PermissionChecker {
|
|||
|
||||
// allow if requesting user is instance owner
|
||||
|
||||
const user = await Db.collections.User.findOneOrFail({
|
||||
const user = await Container.get(UserRepository).findOneOrFail({
|
||||
where: { id: userId },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
@ -38,7 +40,7 @@ export class PermissionChecker {
|
|||
let workflowUserIds = [userId];
|
||||
|
||||
if (workflow.id && isSharingEnabled()) {
|
||||
const workflowSharings = await Db.collections.SharedWorkflow.find({
|
||||
const workflowSharings = await Container.get(SharedWorkflowRepository).find({
|
||||
relations: ['workflow'],
|
||||
where: { workflowId: workflow.id },
|
||||
select: ['userId'],
|
||||
|
@ -54,7 +56,7 @@ export class PermissionChecker {
|
|||
credentialsWhere.roleId = role.id;
|
||||
}
|
||||
|
||||
const credentialSharings = await Db.collections.SharedCredentials.find({
|
||||
const credentialSharings = await Container.get(SharedCredentialsRepository).find({
|
||||
where: credentialsWhere,
|
||||
});
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import { In } from 'typeorm';
|
|||
import { compare, genSaltSync, hash } from 'bcryptjs';
|
||||
import { Container } from 'typedi';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type { WhereClause } from '@/Interfaces';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
@ -11,6 +10,7 @@ import config from '@/config';
|
|||
import { License } from '@/License';
|
||||
import { getWebhookBaseUrl } from '@/WebhookHelpers';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export function isSharingEnabled(): boolean {
|
||||
return Container.get(License).isSharingEnabled();
|
||||
|
@ -19,7 +19,7 @@ export function isSharingEnabled(): boolean {
|
|||
export async function getInstanceOwner() {
|
||||
const globalOwnerRole = await Container.get(RoleService).findGlobalOwnerRole();
|
||||
|
||||
return Db.collections.User.findOneOrFail({
|
||||
return Container.get(UserRepository).findOneOrFail({
|
||||
relations: ['globalRole'],
|
||||
where: {
|
||||
globalRoleId: globalOwnerRole.id,
|
||||
|
@ -77,7 +77,7 @@ export function validatePassword(password?: string): string {
|
|||
}
|
||||
|
||||
export async function getUserById(userId: string): Promise<User> {
|
||||
const user = await Db.collections.User.findOneOrFail({
|
||||
const user = await Container.get(UserRepository).findOneOrFail({
|
||||
where: { id: userId },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import type {
|
|||
} from '@/Interfaces';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import { recoverExecutionDataFromEventLogMessages } from './eventbus/MessageEventBus/recoverEvents';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import type { ExecutionEntity } from '@db/entities/ExecutionEntity';
|
||||
import { OwnershipService } from './services/ownership.service';
|
||||
import { Logger } from '@/Logger';
|
||||
|
|
|
@ -12,7 +12,7 @@ import type {
|
|||
WaitingWebhookRequest,
|
||||
} from '@/Interfaces';
|
||||
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { OwnershipService } from './services/ownership.service';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Container from 'typedi';
|
||||
import type { INode, IWorkflowCredentials } from 'n8n-workflow';
|
||||
import * as Db from '@/Db';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export async function WorkflowCredentials(nodes: INode[]): Promise<IWorkflowCredentials> {
|
||||
|
@ -29,7 +30,7 @@ export async function WorkflowCredentials(nodes: INode[]): Promise<IWorkflowCred
|
|||
}
|
||||
|
||||
if (!returnCredentials[type][nodeCredentials.id]) {
|
||||
foundCredentials = await Db.collections.Credentials.findOneBy({
|
||||
foundCredentials = await Container.get(CredentialsRepository).findOneBy({
|
||||
id: nodeCredentials.id,
|
||||
type,
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ import { findSubworkflowStart, isWorkflowIdValid } from '@/utils';
|
|||
import { PermissionChecker } from './UserManagement/PermissionChecker';
|
||||
import { WorkflowsService } from './workflows/workflows.services';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { EventsService } from '@/services/events.service';
|
||||
import { SecretsHelper } from './SecretsHelpers';
|
||||
import { OwnershipService } from './services/ownership.service';
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
Workflow,
|
||||
} from 'n8n-workflow';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import * as Db from '@/Db';
|
||||
import omit from 'lodash/omit';
|
||||
import type {
|
||||
ExecutionPayload,
|
||||
IWorkflowErrorData,
|
||||
|
@ -32,15 +32,18 @@ import { WorkflowRunner } from '@/WorkflowRunner';
|
|||
import config from '@/config';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import type { User } from '@db/entities/User';
|
||||
import omit from 'lodash/omit';
|
||||
import { PermissionChecker } from './UserManagement/PermissionChecker';
|
||||
import { UserService } from './services/user.service';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import type { SharedWorkflow } from '@db/entities/SharedWorkflow';
|
||||
import type { RoleNames } from '@db/entities/Role';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { RoleRepository } from '@db/repositories/role.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { RoleService } from './services/role.service';
|
||||
import { ExecutionRepository, RoleRepository } from './databases/repositories';
|
||||
import { VariablesService } from './environments/variables/variables.service';
|
||||
import type { CredentialsEntity } from './databases/entities/CredentialsEntity';
|
||||
import { Logger } from './Logger';
|
||||
|
||||
const ERROR_TRIGGER_TYPE = config.getEnv('nodes.errorTriggerType');
|
||||
|
@ -144,7 +147,7 @@ export async function executeErrorWorkflow(
|
|||
const logger = Container.get(Logger);
|
||||
// Wrap everything in try/catch to make sure that no errors bubble up and all get caught here
|
||||
try {
|
||||
const workflowData = await Db.collections.Workflow.findOneBy({ id: workflowId });
|
||||
const workflowData = await Container.get(WorkflowRepository).findOneBy({ id: workflowId });
|
||||
|
||||
if (workflowData === null) {
|
||||
// The error workflow could not be found
|
||||
|
@ -282,7 +285,7 @@ export async function executeErrorWorkflow(
|
|||
* Returns the static data of workflow
|
||||
*/
|
||||
export async function getStaticDataById(workflowId: string) {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
const workflowData = await Container.get(WorkflowRepository).findOne({
|
||||
select: ['staticData'],
|
||||
where: { id: workflowId },
|
||||
});
|
||||
|
@ -330,7 +333,7 @@ export async function replaceInvalidCredentials(workflow: WorkflowEntity): Promi
|
|||
credentialsByName[nodeCredentialType] = {};
|
||||
}
|
||||
if (credentialsByName[nodeCredentialType][name] === undefined) {
|
||||
const credentials = await Db.collections.Credentials.findBy({
|
||||
const credentials = await Container.get(CredentialsRepository).findBy({
|
||||
name,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -366,7 +369,7 @@ export async function replaceInvalidCredentials(workflow: WorkflowEntity): Promi
|
|||
// check if credentials for ID-type are not yet cached
|
||||
if (credentialsById[nodeCredentialType][nodeCredentials.id] === undefined) {
|
||||
// check first if ID-type combination exists
|
||||
const credentials = await Db.collections.Credentials.findOneBy({
|
||||
const credentials = await Container.get(CredentialsRepository).findOneBy({
|
||||
id: nodeCredentials.id,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -380,7 +383,7 @@ export async function replaceInvalidCredentials(workflow: WorkflowEntity): Promi
|
|||
continue;
|
||||
}
|
||||
// no credentials found for ID, check if some exist for name
|
||||
const credsByName = await Db.collections.Credentials.findBy({
|
||||
const credsByName = await Container.get(CredentialsRepository).findBy({
|
||||
name: nodeCredentials.name,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -429,7 +432,7 @@ export async function getSharedWorkflowIds(user: User, roles?: RoleNames[]): Pro
|
|||
|
||||
where.roleId = In(roleIds);
|
||||
}
|
||||
const sharedWorkflows = await Db.collections.SharedWorkflow.find({
|
||||
const sharedWorkflows = await Container.get(SharedWorkflowRepository).find({
|
||||
where,
|
||||
select: ['workflowId'],
|
||||
});
|
||||
|
@ -444,19 +447,21 @@ export async function isBelowOnboardingThreshold(user: User): Promise<boolean> {
|
|||
const skippedTypes = ['n8n-nodes-base.start', 'n8n-nodes-base.stickyNote'];
|
||||
|
||||
const workflowOwnerRole = await Container.get(RoleService).findWorkflowOwnerRole();
|
||||
const ownedWorkflowsIds = await Db.collections.SharedWorkflow.find({
|
||||
where: {
|
||||
userId: user.id,
|
||||
roleId: workflowOwnerRole?.id,
|
||||
},
|
||||
select: ['workflowId'],
|
||||
}).then((ownedWorkflows) => ownedWorkflows.map(({ workflowId }) => workflowId));
|
||||
const ownedWorkflowsIds = await Container.get(SharedWorkflowRepository)
|
||||
.find({
|
||||
where: {
|
||||
userId: user.id,
|
||||
roleId: workflowOwnerRole?.id,
|
||||
},
|
||||
select: ['workflowId'],
|
||||
})
|
||||
.then((ownedWorkflows) => ownedWorkflows.map(({ workflowId }) => workflowId));
|
||||
|
||||
if (ownedWorkflowsIds.length > 15) {
|
||||
belowThreshold = false;
|
||||
} else {
|
||||
// just fetch workflows' nodes to keep memory footprint low
|
||||
const workflows = await Db.collections.Workflow.find({
|
||||
const workflows = await Container.get(WorkflowRepository).find({
|
||||
where: { id: In(ownedWorkflowsIds) },
|
||||
select: ['nodes'],
|
||||
});
|
||||
|
|
|
@ -48,7 +48,7 @@ import { PermissionChecker } from '@/UserManagement/PermissionChecker';
|
|||
import { Push } from '@/push';
|
||||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from './InternalHooks';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { Logger } from './Logger';
|
||||
|
||||
export class WorkflowRunner {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import * as Db from '@/Db';
|
||||
import { separate } from '@/utils';
|
||||
import config from '@/config';
|
||||
import { RISK_CATEGORIES } from '@/audit/constants';
|
||||
|
@ -9,6 +8,8 @@ import { reportNodesRisk } from '@/audit/risks/nodes.risk';
|
|||
import { reportFilesystemRisk } from '@/audit/risks/filesystem.risk';
|
||||
import { reportInstanceRisk } from '@/audit/risks/instance.risk';
|
||||
import type { Risk } from '@/audit/types';
|
||||
import Container from 'typedi';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
export const SYNC_MAP: Record<string, Risk.SyncReportFn> = {
|
||||
database: reportDatabaseRisk,
|
||||
|
@ -35,7 +36,7 @@ export async function audit(
|
|||
config.set('security.audit.daysAbandonedWorkflow', daysAbandonedWorkflow);
|
||||
}
|
||||
|
||||
const workflows = await Db.collections.Workflow.find({
|
||||
const workflows = await Container.get(WorkflowRepository).find({
|
||||
select: ['id', 'name', 'active', 'nodes', 'connections'],
|
||||
});
|
||||
|
||||
|
|
|
@ -6,11 +6,9 @@ import config from '@/config';
|
|||
import { CREDENTIALS_REPORT } from '@/audit/constants';
|
||||
import type { Risk } from '@/audit/types';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import {
|
||||
CredentialsRepository,
|
||||
ExecutionDataRepository,
|
||||
ExecutionRepository,
|
||||
} from '@db/repositories';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { ExecutionDataRepository } from '@db/repositories/executionData.repository';
|
||||
|
||||
async function getAllCredsInUse(workflows: WorkflowEntity[]) {
|
||||
const credsInAnyUse = new Set<string>();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import type { Response } from 'express';
|
||||
import { createHash } from 'crypto';
|
||||
import * as Db from '@/Db';
|
||||
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from '@/constants';
|
||||
import type { JwtPayload, JwtToken } from '@/Interfaces';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
@ -9,6 +8,7 @@ import config from '@/config';
|
|||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import { License } from '@/License';
|
||||
import { Container } from 'typedi';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export function issueJWT(user: User): JwtToken {
|
||||
const { id, email, password } = user;
|
||||
|
@ -50,7 +50,7 @@ export const createPasswordSha = (user: User) =>
|
|||
.digest('hex');
|
||||
|
||||
export async function resolveJwtContent(jwtPayload: JwtPayload): Promise<User> {
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Container.get(UserRepository).findOne({
|
||||
where: { id: jwtPayload.id },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import * as Db from '@/Db';
|
||||
import type { User } from '@db/entities/User';
|
||||
import { compareHash } from '@/UserManagement/UserManagementHelper';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { isLdapLoginEnabled } from '@/Ldap/helpers';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export const handleEmailLogin = async (
|
||||
email: string,
|
||||
password: string,
|
||||
): Promise<User | undefined> => {
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Container.get(UserRepository).findOne({
|
||||
where: { email },
|
||||
relations: ['globalRole', 'authIdentities'],
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type { Workflow } from 'n8n-workflow';
|
||||
import { Service } from 'typedi';
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import { PostHogClient } from '@/posthog';
|
|||
import { License } from '@/License';
|
||||
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
|
||||
import { initExpressionEvaluator } from '@/ExpressionEvalator';
|
||||
import { generateHostInstanceId } from '../databases/utils/generators';
|
||||
import { generateHostInstanceId } from '@db/utils/generators';
|
||||
import { WorkflowHistoryManager } from '@/workflows/workflowHistory/workflowHistoryManager.ee';
|
||||
|
||||
export abstract class BaseCommand extends Command {
|
||||
|
|
|
@ -5,13 +5,13 @@ import type { IWorkflowBase } from 'n8n-workflow';
|
|||
import { ExecutionBaseError } from 'n8n-workflow';
|
||||
|
||||
import { ActiveExecutions } from '@/ActiveExecutions';
|
||||
import * as Db from '@/Db';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import type { IWorkflowExecutionDataProcess } from '@/Interfaces';
|
||||
import { getInstanceOwner } from '@/UserManagement/UserManagementHelper';
|
||||
import { findCliWorkflowStart, isWorkflowIdValid } from '@/utils';
|
||||
import { BaseCommand } from './BaseCommand';
|
||||
import { Container } from 'typedi';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
export class Execute extends BaseCommand {
|
||||
static description = '\nExecutes a given workflow';
|
||||
|
@ -81,7 +81,7 @@ export class Execute extends BaseCommand {
|
|||
if (flags.id) {
|
||||
// Id of workflow is given
|
||||
workflowId = flags.id;
|
||||
workflowData = await Db.collections.Workflow.findOneBy({ id: workflowId });
|
||||
workflowData = await Container.get(WorkflowRepository).findOneBy({ id: workflowId });
|
||||
if (workflowData === null) {
|
||||
this.logger.info(`The workflow with the id "${workflowId}" does not exist.`);
|
||||
process.exit(1);
|
||||
|
|
|
@ -9,7 +9,6 @@ import { diff } from 'json-diff';
|
|||
import pick from 'lodash/pick';
|
||||
|
||||
import { ActiveExecutions } from '@/ActiveExecutions';
|
||||
import * as Db from '@/Db';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import type { IWorkflowDb, IWorkflowExecutionDataProcess } from '@/Interfaces';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
@ -24,6 +23,7 @@ import type {
|
|||
IResult,
|
||||
IWorkflowExecutionProgress,
|
||||
} from '../types/commands.types';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
const re = /\d+/;
|
||||
|
||||
|
@ -278,7 +278,7 @@ export class ExecuteBatch extends BaseCommand {
|
|||
|
||||
ExecuteBatch.instanceOwner = await getInstanceOwner();
|
||||
|
||||
const query = Db.collections.Workflow.createQueryBuilder('workflows');
|
||||
const query = Container.get(WorkflowRepository).createQueryBuilder('workflows');
|
||||
|
||||
if (ids.length > 0) {
|
||||
query.andWhere('workflows.id in (:...ids)', { ids });
|
||||
|
|
|
@ -3,9 +3,10 @@ import fs from 'fs';
|
|||
import path from 'path';
|
||||
import type { FindOptionsWhere } from 'typeorm';
|
||||
import { Credentials } from 'n8n-core';
|
||||
import * as Db from '@/Db';
|
||||
import type { ICredentialsDb, ICredentialsDecryptedDb } from '@/Interfaces';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
export class ExportCredentialsCommand extends BaseCommand {
|
||||
static description = 'Export credentials';
|
||||
|
@ -110,7 +111,8 @@ export class ExportCredentialsCommand extends BaseCommand {
|
|||
findQuery.id = flags.id;
|
||||
}
|
||||
|
||||
const credentials: ICredentialsDb[] = await Db.collections.Credentials.findBy(findQuery);
|
||||
const credentials: ICredentialsDb[] =
|
||||
await Container.get(CredentialsRepository).findBy(findQuery);
|
||||
|
||||
if (flags.decrypted) {
|
||||
for (let i = 0; i < credentials.length; i++) {
|
||||
|
|
|
@ -2,9 +2,10 @@ import { flags } from '@oclif/command';
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import type { FindOptionsWhere } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
export class ExportWorkflowsCommand extends BaseCommand {
|
||||
static description = 'Export workflows';
|
||||
|
@ -104,7 +105,7 @@ export class ExportWorkflowsCommand extends BaseCommand {
|
|||
findQuery.id = flags.id;
|
||||
}
|
||||
|
||||
const workflows = await Db.collections.Workflow.find({
|
||||
const workflows = await Container.get(WorkflowRepository).find({
|
||||
where: findQuery,
|
||||
relations: ['tags'],
|
||||
});
|
||||
|
|
|
@ -15,6 +15,7 @@ import type { ICredentialsEncrypted } from 'n8n-workflow';
|
|||
import { jsonParse } from 'n8n-workflow';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { UM_FIX_INSTRUCTION } from '@/constants';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export class ImportCredentialsCommand extends BaseCommand {
|
||||
static description = 'Import credentials';
|
||||
|
@ -175,7 +176,7 @@ export class ImportCredentialsCommand extends BaseCommand {
|
|||
|
||||
const owner =
|
||||
ownerGlobalRole &&
|
||||
(await Db.collections.User.findOneBy({ globalRoleId: ownerGlobalRole.id }));
|
||||
(await Container.get(UserRepository).findOneBy({ globalRoleId: ownerGlobalRole.id }));
|
||||
|
||||
if (!owner) {
|
||||
throw new Error(`Failed to find owner. ${UM_FIX_INSTRUCTION}`);
|
||||
|
@ -185,7 +186,7 @@ export class ImportCredentialsCommand extends BaseCommand {
|
|||
}
|
||||
|
||||
private async getAssignee(userId: string) {
|
||||
const user = await Db.collections.User.findOneBy({ id: userId });
|
||||
const user = await Container.get(UserRepository).findOneBy({ id: userId });
|
||||
|
||||
if (!user) {
|
||||
throw new Error(`Failed to find user with ID ${userId}`);
|
||||
|
|
|
@ -19,6 +19,8 @@ import { generateNanoId } from '@db/utils/generators';
|
|||
import { RoleService } from '@/services/role.service';
|
||||
import { TagService } from '@/services/tag.service';
|
||||
import { UM_FIX_INSTRUCTION } from '@/constants';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
|
||||
function assertHasWorkflowsToImport(workflows: unknown): asserts workflows is IWorkflowToImport[] {
|
||||
if (!Array.isArray(workflows)) {
|
||||
|
@ -95,7 +97,7 @@ export class ImportWorkflowsCommand extends BaseCommand {
|
|||
await this.initOwnerWorkflowRole();
|
||||
const user = flags.userId ? await this.getAssignee(flags.userId) : await this.getOwner();
|
||||
|
||||
const credentials = await Db.collections.Credentials.find();
|
||||
const credentials = await Container.get(CredentialsRepository).find();
|
||||
const tags = await this.tagService.getAll();
|
||||
|
||||
let totalImported = 0;
|
||||
|
@ -239,7 +241,7 @@ export class ImportWorkflowsCommand extends BaseCommand {
|
|||
|
||||
const owner =
|
||||
ownerGlobalRole &&
|
||||
(await Db.collections.User.findOneBy({ globalRoleId: ownerGlobalRole?.id }));
|
||||
(await Container.get(UserRepository).findOneBy({ globalRoleId: ownerGlobalRole?.id }));
|
||||
|
||||
if (!owner) {
|
||||
throw new Error(`Failed to find owner. ${UM_FIX_INSTRUCTION}`);
|
||||
|
@ -249,7 +251,7 @@ export class ImportWorkflowsCommand extends BaseCommand {
|
|||
}
|
||||
|
||||
private async getAssignee(userId: string) {
|
||||
const user = await Db.collections.User.findOneBy({ id: userId });
|
||||
const user = await Container.get(UserRepository).findOneBy({ id: userId });
|
||||
|
||||
if (!user) {
|
||||
throw new Error(`Failed to find user with ID ${userId}`);
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
import * as Db from '@/Db';
|
||||
import Container from 'typedi';
|
||||
import { LDAP_DEFAULT_CONFIGURATION, LDAP_FEATURE_NAME } from '@/Ldap/constants';
|
||||
import { In } from 'typeorm';
|
||||
import { AuthIdentityRepository } from '@db/repositories/authIdentity.repository';
|
||||
import { AuthProviderSyncHistoryRepository } from '@db/repositories/authProviderSyncHistory.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
|
||||
export class Reset extends BaseCommand {
|
||||
static description = '\nResets the database to the default ldap state';
|
||||
|
||||
async run(): Promise<void> {
|
||||
const { AuthIdentity, AuthProviderSyncHistory, Settings, User } = Db.collections;
|
||||
const ldapIdentities = await AuthIdentity.find({
|
||||
const ldapIdentities = await Container.get(AuthIdentityRepository).find({
|
||||
where: { providerType: 'ldap' },
|
||||
select: ['userId'],
|
||||
});
|
||||
await AuthProviderSyncHistory.delete({ providerType: 'ldap' });
|
||||
await AuthIdentity.delete({ providerType: 'ldap' });
|
||||
await User.delete({ id: In(ldapIdentities.map((i) => i.userId)) });
|
||||
await Settings.delete({ key: LDAP_FEATURE_NAME });
|
||||
await Settings.insert({
|
||||
await Container.get(AuthProviderSyncHistoryRepository).delete({ providerType: 'ldap' });
|
||||
await Container.get(AuthIdentityRepository).delete({ providerType: 'ldap' });
|
||||
await Container.get(UserRepository).delete({ id: In(ldapIdentities.map((i) => i.userId)) });
|
||||
await Container.get(SettingsRepository).delete({ key: LDAP_FEATURE_NAME });
|
||||
await Container.get(SettingsRepository).insert({
|
||||
key: LDAP_FEATURE_NAME,
|
||||
value: JSON.stringify(LDAP_DEFAULT_CONFIGURATION),
|
||||
loadOnStartup: true,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as Db from '@/Db';
|
||||
import { SETTINGS_LICENSE_CERT_KEY } from '@/constants';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
export class ClearLicenseCommand extends BaseCommand {
|
||||
static description = 'Clear license';
|
||||
|
@ -9,7 +10,7 @@ export class ClearLicenseCommand extends BaseCommand {
|
|||
|
||||
async run() {
|
||||
this.logger.info('Clearing license from database.');
|
||||
await Db.collections.Settings.delete({
|
||||
await Container.get(SettingsRepository).delete({
|
||||
key: SETTINGS_LICENSE_CERT_KEY,
|
||||
});
|
||||
this.logger.info('Done. Restart n8n to take effect.');
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { flags } from '@oclif/command';
|
||||
import type { FindOptionsWhere } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
export class ListWorkflowCommand extends BaseCommand {
|
||||
static description = '\nList workflows';
|
||||
|
@ -36,7 +37,7 @@ export class ListWorkflowCommand extends BaseCommand {
|
|||
findQuery.active = flags.active === 'true';
|
||||
}
|
||||
|
||||
const workflows = await Db.collections.Workflow.findBy(findQuery);
|
||||
const workflows = await Container.get(WorkflowRepository).findBy(findQuery);
|
||||
if (flags.onlyId) {
|
||||
workflows.forEach((workflow) => this.logger.info(workflow.id));
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { flags } from '@oclif/command';
|
||||
import * as Db from '@/Db';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import Container from 'typedi';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
|
||||
export class DisableMFACommand extends BaseCommand {
|
||||
static description = 'Disable MFA authentication for a user';
|
||||
|
@ -27,7 +28,7 @@ export class DisableMFACommand extends BaseCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
const updateOperationResult = await Db.collections.User.update(
|
||||
const updateOperationResult = await Container.get(UserRepository).update(
|
||||
{ email: flags.email },
|
||||
{ mfaSecret: null, mfaRecoveryCodes: [], mfaEnabled: false },
|
||||
);
|
||||
|
|
|
@ -18,7 +18,6 @@ import config from '@/config';
|
|||
|
||||
import { ActiveExecutions } from '@/ActiveExecutions';
|
||||
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||
import * as Db from '@/Db';
|
||||
import * as GenericHelpers from '@/GenericHelpers';
|
||||
import { Server } from '@/Server';
|
||||
import { EDITOR_UI_DIST_DIR, LICENSE_FEATURES } from '@/constants';
|
||||
|
@ -30,6 +29,8 @@ import { IConfig } from '@oclif/config';
|
|||
import { SingleMainInstancePublisher } from '@/services/orchestration/main/SingleMainInstance.publisher';
|
||||
import { OrchestrationHandlerMainService } from '@/services/orchestration/main/orchestration.handler.main.service';
|
||||
import { PruningService } from '@/services/pruning.service';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
||||
const open = require('open');
|
||||
|
@ -286,7 +287,9 @@ export class Start extends BaseCommand {
|
|||
}
|
||||
|
||||
// Load settings from database and set them to config.
|
||||
const databaseSettings = await Db.collections.Settings.findBy({ loadOnStartup: true });
|
||||
const databaseSettings = await Container.get(SettingsRepository).findBy({
|
||||
loadOnStartup: true,
|
||||
});
|
||||
databaseSettings.forEach((setting) => {
|
||||
config.set(setting.key, jsonParse(setting.value, { fallbackValue: setting.value }));
|
||||
});
|
||||
|
@ -304,7 +307,7 @@ export class Start extends BaseCommand {
|
|||
if (dbType === 'sqlite') {
|
||||
const shouldRunVacuum = config.getEnv('database.sqlite.executeVacuumOnStartup');
|
||||
if (shouldRunVacuum) {
|
||||
await Db.collections.Execution.query('VACUUM;');
|
||||
await Container.get(ExecutionRepository).query('VACUUM;');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { flags } from '@oclif/command';
|
||||
import type { FindOptionsWhere } from 'typeorm';
|
||||
import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||
import * as Db from '@/Db';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
export class UpdateWorkflowCommand extends BaseCommand {
|
||||
static description = 'Update workflows';
|
||||
|
@ -64,7 +65,7 @@ export class UpdateWorkflowCommand extends BaseCommand {
|
|||
findQuery.active = true;
|
||||
}
|
||||
|
||||
await Db.collections.Workflow.update(findQuery, updateQuery);
|
||||
await Container.get(WorkflowRepository).update(findQuery, updateQuery);
|
||||
this.logger.info('Done');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import { Container } from 'typedi';
|
||||
import { Not } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import { User } from '@db/entities/User';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { BaseCommand } from '../BaseCommand';
|
||||
|
||||
const defaultUserProps = {
|
||||
firstName: null,
|
||||
|
@ -24,34 +28,34 @@ export class Reset extends BaseCommand {
|
|||
const ownerWorkflowRole = await Container.get(RoleService).findWorkflowOwnerRole();
|
||||
const ownerCredentialRole = await Container.get(RoleService).findCredentialOwnerRole();
|
||||
|
||||
await Db.collections.SharedWorkflow.update(
|
||||
await Container.get(SharedWorkflowRepository).update(
|
||||
{ userId: Not(owner.id), roleId: ownerWorkflowRole.id },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
await Db.collections.SharedCredentials.update(
|
||||
await Container.get(SharedCredentialsRepository).update(
|
||||
{ userId: Not(owner.id), roleId: ownerCredentialRole.id },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
await Db.collections.User.delete({ id: Not(owner.id) });
|
||||
await Db.collections.User.save(Object.assign(owner, defaultUserProps));
|
||||
await Container.get(UserRepository).delete({ id: Not(owner.id) });
|
||||
await Container.get(UserRepository).save(Object.assign(owner, defaultUserProps));
|
||||
|
||||
const danglingCredentials: CredentialsEntity[] =
|
||||
await Db.collections.Credentials.createQueryBuilder('credentials')
|
||||
.leftJoinAndSelect('credentials.shared', 'shared')
|
||||
.where('shared.credentialsId is null')
|
||||
.getMany();
|
||||
const danglingCredentials: CredentialsEntity[] = await Container.get(CredentialsRepository)
|
||||
.createQueryBuilder('credentials')
|
||||
.leftJoinAndSelect('credentials.shared', 'shared')
|
||||
.where('shared.credentialsId is null')
|
||||
.getMany();
|
||||
const newSharedCredentials = danglingCredentials.map((credentials) =>
|
||||
Db.collections.SharedCredentials.create({
|
||||
Container.get(SharedCredentialsRepository).create({
|
||||
credentials,
|
||||
user: owner,
|
||||
role: ownerCredentialRole,
|
||||
}),
|
||||
);
|
||||
await Db.collections.SharedCredentials.save(newSharedCredentials);
|
||||
await Container.get(SharedCredentialsRepository).save(newSharedCredentials);
|
||||
|
||||
await Db.collections.Settings.update(
|
||||
await Container.get(SettingsRepository).update(
|
||||
{ key: 'userManagement.isInstanceOwnerSetUp' },
|
||||
{ value: 'false' },
|
||||
);
|
||||
|
@ -62,7 +66,7 @@ export class Reset extends BaseCommand {
|
|||
async getInstanceOwner(): Promise<User> {
|
||||
const globalRole = await Container.get(RoleService).findGlobalOwnerRole();
|
||||
|
||||
const owner = await Db.collections.User.findOneBy({ globalRoleId: globalRole.id });
|
||||
const owner = await Container.get(UserRepository).findOneBy({ globalRoleId: globalRole.id });
|
||||
|
||||
if (owner) return owner;
|
||||
|
||||
|
@ -70,9 +74,9 @@ export class Reset extends BaseCommand {
|
|||
|
||||
Object.assign(user, { ...defaultUserProps, globalRole });
|
||||
|
||||
await Db.collections.User.save(user);
|
||||
await Container.get(UserRepository).save(user);
|
||||
|
||||
return Db.collections.User.findOneByOrFail({ globalRoleId: globalRole.id });
|
||||
return Container.get(UserRepository).findOneByOrFail({ globalRoleId: globalRole.id });
|
||||
}
|
||||
|
||||
async catch(error: Error): Promise<void> {
|
||||
|
|
|
@ -27,7 +27,8 @@ import { Queue } from '@/Queue';
|
|||
import { generateFailedExecutionFromError } from '@/WorkflowHelpers';
|
||||
import { N8N_VERSION } from '@/constants';
|
||||
import { BaseCommand } from './BaseCommand';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import type { ICredentialsOverwrite } from '@/Interfaces';
|
||||
import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
||||
|
@ -137,7 +138,7 @@ export class Worker extends BaseCommand {
|
|||
|
||||
let { staticData } = fullExecutionData.workflowData;
|
||||
if (loadStaticData) {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
const workflowData = await Container.get(WorkflowRepository).findOne({
|
||||
select: ['id', 'staticData'],
|
||||
where: {
|
||||
id: workflowId,
|
||||
|
|
|
@ -3,7 +3,9 @@ import { Service } from 'typedi';
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import config from '@/config';
|
||||
import type { Role } from '@db/entities/Role';
|
||||
import { RoleRepository, SettingsRepository, UserRepository } from '@db/repositories';
|
||||
import { RoleRepository } from '@db/repositories/role.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||
import { hashPassword } from '@/UserManagement/UserManagementHelper';
|
||||
import { eventBus } from '@/eventbus/MessageEventBus/MessageEventBus';
|
||||
|
|
|
@ -4,7 +4,8 @@ import type { ICredentialDataDecryptedObject, IWorkflowExecuteAdditionalData } f
|
|||
import config from '@/config';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import type { User } from '@db/entities/User';
|
||||
import { CredentialsRepository, SharedCredentialsRepository } from '@db/repositories';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import type { ICredentialsDb } from '@/Interfaces';
|
||||
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';
|
||||
import type { OAuthRequest } from '@/requests';
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Response } from 'express';
|
|||
import { Config } from '@/config';
|
||||
import { OwnerRequest } from '@/requests';
|
||||
import { IInternalHooksClass } from '@/Interfaces';
|
||||
import { SettingsRepository } from '@db/repositories';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { UserService } from '@/services/user.service';
|
||||
import { Logger } from '@/Logger';
|
||||
|
|
|
@ -29,7 +29,8 @@ import type { PublicUser, ITelemetryUserDeletionData } from '@/Interfaces';
|
|||
import { AuthIdentity } from '@db/entities/AuthIdentity';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { isSamlLicensedAndEnabled } from '../sso/saml/samlHelpers';
|
||||
import { SharedCredentialsRepository, SharedWorkflowRepository } from '@db/repositories';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { License } from '@/License';
|
||||
import { Container } from 'typedi';
|
||||
|
|
|
@ -3,7 +3,8 @@ import { Response, NextFunction } from 'express';
|
|||
import { Get, Middleware, RestController } from '@/decorators';
|
||||
import type { WorkflowStatistics } from '@db/entities/WorkflowStatistics';
|
||||
import { StatisticsNames } from '@db/entities/WorkflowStatistics';
|
||||
import { SharedWorkflowRepository, WorkflowStatisticsRepository } from '@db/repositories';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistics.repository';
|
||||
import { ExecutionRequest } from '@/requests';
|
||||
import { whereClause } from '@/UserManagement/UserManagementHelper';
|
||||
import { NotFoundError } from '@/ResponseHelper';
|
||||
|
|
|
@ -10,7 +10,7 @@ import { EECredentialsService as EECredentials } from './credentials.service.ee'
|
|||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
|
||||
export const EECredentialsController = express.Router();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { DeleteResult, EntityManager, FindOptionsWhere } from 'typeorm';
|
||||
import { In, Not } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
@ -8,6 +7,7 @@ import { UserService } from '@/services/user.service';
|
|||
import { CredentialsService } from './credentials.service';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import Container from 'typedi';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
|
||||
export class EECredentialsService extends CredentialsService {
|
||||
static async isOwned(
|
||||
|
@ -43,7 +43,7 @@ export class EECredentialsService extends CredentialsService {
|
|||
where.userId = user.id;
|
||||
}
|
||||
|
||||
return Db.collections.SharedCredentials.findOne({
|
||||
return Container.get(SharedCredentialsRepository).findOne({
|
||||
where,
|
||||
relations,
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ export class EECredentialsService extends CredentialsService {
|
|||
const newSharedCredentials = users
|
||||
.filter((user) => !user.isPending)
|
||||
.map((user) =>
|
||||
Db.collections.SharedCredentials.create({
|
||||
Container.get(SharedCredentialsRepository).create({
|
||||
credentialsId: credential.id,
|
||||
userId: user.id,
|
||||
roleId: role?.id,
|
||||
|
|
|
@ -25,13 +25,15 @@ import { CredentialTypes } from '@/CredentialTypes';
|
|||
import { RoleService } from '@/services/role.service';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { Logger } from '@/Logger';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
|
||||
export class CredentialsService {
|
||||
static async get(
|
||||
where: FindOptionsWhere<ICredentialsDb>,
|
||||
options?: { relations: string[] },
|
||||
): Promise<ICredentialsDb | null> {
|
||||
return Db.collections.Credentials.findOne({
|
||||
return Container.get(CredentialsRepository).findOne({
|
||||
relations: options?.relations,
|
||||
where,
|
||||
});
|
||||
|
@ -88,14 +90,14 @@ export class CredentialsService {
|
|||
const isDefaultSelect = !options.listQueryOptions?.select;
|
||||
|
||||
if (returnAll) {
|
||||
const credentials = await Db.collections.Credentials.find(findManyOptions);
|
||||
const credentials = await Container.get(CredentialsRepository).find(findManyOptions);
|
||||
|
||||
return isDefaultSelect ? this.addOwnedByAndSharedWith(credentials) : credentials;
|
||||
}
|
||||
|
||||
const ids = await this.getAccessibleCredentials(user.id);
|
||||
|
||||
const credentials = await Db.collections.Credentials.find({
|
||||
const credentials = await Container.get(CredentialsRepository).find({
|
||||
...findManyOptions,
|
||||
where: { ...findManyOptions.where, id: In(ids) }, // only accessible credentials
|
||||
});
|
||||
|
@ -107,7 +109,7 @@ export class CredentialsService {
|
|||
* Get the IDs of all credentials owned by or shared with a user.
|
||||
*/
|
||||
private static async getAccessibleCredentials(userId: string) {
|
||||
const sharings = await Db.collections.SharedCredentials.find({
|
||||
const sharings = await Container.get(SharedCredentialsRepository).find({
|
||||
relations: ['role'],
|
||||
where: {
|
||||
userId,
|
||||
|
@ -125,7 +127,7 @@ export class CredentialsService {
|
|||
options.relations = ['shared', 'shared.user', 'shared.role'];
|
||||
}
|
||||
|
||||
return Db.collections.Credentials.find(options);
|
||||
return Container.get(CredentialsRepository).find(options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,7 +154,7 @@ export class CredentialsService {
|
|||
}
|
||||
}
|
||||
|
||||
return Db.collections.SharedCredentials.findOne({ where, relations });
|
||||
return Container.get(SharedCredentialsRepository).findOne({ where, relations });
|
||||
}
|
||||
|
||||
static async prepareCreateData(
|
||||
|
@ -162,7 +164,7 @@ export class CredentialsService {
|
|||
|
||||
// This saves us a merge but requires some type casting. These
|
||||
// types are compatible for this case.
|
||||
const newCredentials = Db.collections.Credentials.create(rest as ICredentialsDb);
|
||||
const newCredentials = Container.get(CredentialsRepository).create(rest as ICredentialsDb);
|
||||
|
||||
await validateEntity(newCredentials);
|
||||
|
||||
|
@ -185,7 +187,7 @@ export class CredentialsService {
|
|||
|
||||
// This saves us a merge but requires some type casting. These
|
||||
// types are compatible for this case.
|
||||
const updateData = Db.collections.Credentials.create(mergedData as ICredentialsDb);
|
||||
const updateData = Container.get(CredentialsRepository).create(mergedData as ICredentialsDb);
|
||||
|
||||
await validateEntity(updateData);
|
||||
|
||||
|
@ -234,11 +236,11 @@ export class CredentialsService {
|
|||
await Container.get(ExternalHooks).run('credentials.update', [newCredentialData]);
|
||||
|
||||
// Update the credentials in DB
|
||||
await Db.collections.Credentials.update(credentialId, newCredentialData);
|
||||
await Container.get(CredentialsRepository).update(credentialId, newCredentialData);
|
||||
|
||||
// We sadly get nothing back from "update". Neither if it updated a record
|
||||
// nor the new value. So query now the updated entry.
|
||||
return Db.collections.Credentials.findOneBy({ id: credentialId });
|
||||
return Container.get(CredentialsRepository).findOneBy({ id: credentialId });
|
||||
}
|
||||
|
||||
static async save(
|
||||
|
@ -281,7 +283,7 @@ export class CredentialsService {
|
|||
static async delete(credentials: CredentialsEntity): Promise<void> {
|
||||
await Container.get(ExternalHooks).run('credentials.delete', [credentials.id]);
|
||||
|
||||
await Db.collections.Credentials.remove(credentials);
|
||||
await Container.get(CredentialsRepository).remove(credentials);
|
||||
}
|
||||
|
||||
static async test(
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
export { AuthIdentityRepository } from './authIdentity.repository';
|
||||
export { AuthProviderSyncHistoryRepository } from './authProviderSyncHistory.repository';
|
||||
export { CredentialsRepository } from './credentials.repository';
|
||||
export { EventDestinationsRepository } from './eventDestinations.repository';
|
||||
export { ExecutionDataRepository } from './executionData.repository';
|
||||
export { ExecutionMetadataRepository } from './executionMetadata.repository';
|
||||
export { ExecutionRepository } from './execution.repository';
|
||||
export { InstalledNodesRepository } from './installedNodes.repository';
|
||||
export { InstalledPackagesRepository } from './installedPackages.repository';
|
||||
export { RoleRepository } from './role.repository';
|
||||
export { SettingsRepository } from './settings.repository';
|
||||
export { SharedCredentialsRepository } from './sharedCredentials.repository';
|
||||
export { SharedWorkflowRepository } from './sharedWorkflow.repository';
|
||||
export { TagRepository } from './tag.repository';
|
||||
export { UserRepository } from './user.repository';
|
||||
export { VariablesRepository } from './variables.repository';
|
||||
export { WebhookRepository } from './webhook.repository';
|
||||
export { WorkflowHistoryRepository } from './workflowHistory.repository';
|
||||
export { WorkflowRepository } from './workflow.repository';
|
||||
export { WorkflowStatisticsRepository } from './workflowStatistics.repository';
|
||||
export { WorkflowTagMappingRepository } from './workflowTagMapping.repository';
|
|
@ -33,7 +33,7 @@ import type { Variables } from '@db/entities/Variables';
|
|||
import type { SourceControlWorkflowVersionId } from './types/sourceControlWorkflowVersionId';
|
||||
import type { ExportableCredential } from './types/exportableCredential';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { TagRepository } from '@/databases/repositories';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
@Service()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Service } from 'typedi';
|
||||
import Container, { Service } from 'typedi';
|
||||
import path from 'path';
|
||||
import {
|
||||
SOURCE_CONTROL_CREDENTIAL_EXPORT_FOLDER,
|
||||
|
@ -6,7 +6,6 @@ import {
|
|||
SOURCE_CONTROL_TAGS_EXPORT_FILE,
|
||||
SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER,
|
||||
} from './constants';
|
||||
import * as Db from '@/Db';
|
||||
import type { ICredentialDataDecryptedObject } from 'n8n-workflow';
|
||||
import { writeFile as fsWriteFile, rm as fsRm } from 'fs/promises';
|
||||
import { rmSync } from 'fs';
|
||||
|
@ -25,8 +24,12 @@ import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
|||
import { In } from 'typeorm';
|
||||
import type { SourceControlledFile } from './types/sourceControlledFile';
|
||||
import { VariablesService } from '../variables/variables.service';
|
||||
import { TagRepository } from '@/databases/repositories';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowTagMappingRepository } from '@db/repositories/workflowTagMapping.repository';
|
||||
|
||||
@Service()
|
||||
export class SourceControlExportService {
|
||||
|
@ -102,7 +105,7 @@ export class SourceControlExportService {
|
|||
try {
|
||||
sourceControlFoldersExistCheck([this.workflowExportFolder]);
|
||||
const workflowIds = candidates.map((e) => e.id);
|
||||
const sharedWorkflows = await Db.collections.SharedWorkflow.find({
|
||||
const sharedWorkflows = await Container.get(SharedWorkflowRepository).find({
|
||||
relations: ['role', 'user'],
|
||||
where: {
|
||||
role: {
|
||||
|
@ -112,7 +115,7 @@ export class SourceControlExportService {
|
|||
workflowId: In(workflowIds),
|
||||
},
|
||||
});
|
||||
const workflows = await Db.collections.Workflow.find({
|
||||
const workflows = await Container.get(WorkflowRepository).find({
|
||||
where: {
|
||||
id: In(workflowIds),
|
||||
},
|
||||
|
@ -181,7 +184,7 @@ export class SourceControlExportService {
|
|||
files: [],
|
||||
};
|
||||
}
|
||||
const mappings = await Db.collections.WorkflowTagMapping.find();
|
||||
const mappings = await Container.get(WorkflowTagMappingRepository).find();
|
||||
const fileName = path.join(this.gitFolder, SOURCE_CONTROL_TAGS_EXPORT_FILE);
|
||||
await fsWriteFile(
|
||||
fileName,
|
||||
|
@ -236,7 +239,7 @@ export class SourceControlExportService {
|
|||
try {
|
||||
sourceControlFoldersExistCheck([this.credentialExportFolder]);
|
||||
const credentialIds = candidates.map((e) => e.id);
|
||||
const credentialsToBeExported = await Db.collections.SharedCredentials.find({
|
||||
const credentialsToBeExported = await Container.get(SharedCredentialsRepository).find({
|
||||
relations: ['credentials', 'role', 'user'],
|
||||
where: {
|
||||
credentialsId: In(credentialIds),
|
||||
|
|
|
@ -7,7 +7,6 @@ import {
|
|||
SOURCE_CONTROL_VARIABLES_EXPORT_FILE,
|
||||
SOURCE_CONTROL_WORKFLOW_EXPORT_FOLDER,
|
||||
} from './constants';
|
||||
import * as Db from '@/Db';
|
||||
import glob from 'fast-glob';
|
||||
import { jsonParse } from 'n8n-workflow';
|
||||
import { readFile as fsReadFile } from 'fs/promises';
|
||||
|
@ -26,9 +25,16 @@ import { getCredentialExportPath, getWorkflowExportPath } from './sourceControlH
|
|||
import type { SourceControlledFile } from './types/sourceControlledFile';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { VariablesService } from '../variables/variables.service';
|
||||
import { TagRepository } from '@/databases/repositories';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { UM_FIX_INSTRUCTION } from '@/constants';
|
||||
import { Logger } from '@/Logger';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { SharedCredentialsRepository } from '@db/repositories/sharedCredentials.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowTagMappingRepository } from '@db/repositories/workflowTagMapping.repository';
|
||||
import { VariablesRepository } from '@db/repositories/variables.repository';
|
||||
|
||||
@Service()
|
||||
export class SourceControlImportService {
|
||||
|
@ -110,7 +116,7 @@ export class SourceControlImportService {
|
|||
}
|
||||
|
||||
public async getLocalVersionIdsFromDb(): Promise<SourceControlWorkflowVersionId[]> {
|
||||
const localWorkflows = await Db.collections.Workflow.find({
|
||||
const localWorkflows = await Container.get(WorkflowRepository).find({
|
||||
select: ['id', 'name', 'versionId', 'updatedAt'],
|
||||
});
|
||||
return localWorkflows.map((local) => ({
|
||||
|
@ -153,7 +159,7 @@ export class SourceControlImportService {
|
|||
public async getLocalCredentialsFromDb(): Promise<
|
||||
Array<ExportableCredential & { filename: string }>
|
||||
> {
|
||||
const localCredentials = await Db.collections.Credentials.find({
|
||||
const localCredentials = await Container.get(CredentialsRepository).find({
|
||||
select: ['id', 'name', 'type', 'nodesAccess'],
|
||||
});
|
||||
return localCredentials.map((local) => ({
|
||||
|
@ -209,7 +215,7 @@ export class SourceControlImportService {
|
|||
const localTags = await this.tagRepository.find({
|
||||
select: ['id', 'name'],
|
||||
});
|
||||
const localMappings = await Db.collections.WorkflowTagMapping.find({
|
||||
const localMappings = await Container.get(WorkflowTagMappingRepository).find({
|
||||
select: ['workflowId', 'tagId'],
|
||||
});
|
||||
return { tags: localTags, mappings: localMappings };
|
||||
|
@ -219,13 +225,13 @@ export class SourceControlImportService {
|
|||
const ownerWorkflowRole = await this.getWorkflowOwnerRole();
|
||||
const workflowRunner = this.activeWorkflowRunner;
|
||||
const candidateIds = candidates.map((c) => c.id);
|
||||
const existingWorkflows = await Db.collections.Workflow.find({
|
||||
const existingWorkflows = await Container.get(WorkflowRepository).find({
|
||||
where: {
|
||||
id: In(candidateIds),
|
||||
},
|
||||
select: ['id', 'name', 'versionId', 'active'],
|
||||
});
|
||||
const allSharedWorkflows = await Db.collections.SharedWorkflow.find({
|
||||
const allSharedWorkflows = await Container.get(SharedWorkflowRepository).find({
|
||||
where: {
|
||||
workflowId: In(candidateIds),
|
||||
},
|
||||
|
@ -244,7 +250,10 @@ export class SourceControlImportService {
|
|||
const existingWorkflow = existingWorkflows.find((e) => e.id === importedWorkflow.id);
|
||||
importedWorkflow.active = existingWorkflow?.active ?? false;
|
||||
this.logger.debug(`Updating workflow id ${importedWorkflow.id ?? 'new'}`);
|
||||
const upsertResult = await Db.collections.Workflow.upsert({ ...importedWorkflow }, ['id']);
|
||||
const upsertResult = await Container.get(WorkflowRepository).upsert(
|
||||
{ ...importedWorkflow },
|
||||
['id'],
|
||||
);
|
||||
if (upsertResult?.identifiers?.length !== 1) {
|
||||
throw new Error(`Failed to upsert workflow ${importedWorkflow.id ?? 'new'}`);
|
||||
}
|
||||
|
@ -254,7 +263,7 @@ export class SourceControlImportService {
|
|||
if (cachedOwnerIds.has(importedWorkflow.owner)) {
|
||||
workflowOwnerId = cachedOwnerIds.get(importedWorkflow.owner) ?? userId;
|
||||
} else {
|
||||
const foundUser = await Db.collections.User.findOne({
|
||||
const foundUser = await Container.get(UserRepository).findOne({
|
||||
where: {
|
||||
email: importedWorkflow.owner,
|
||||
},
|
||||
|
@ -278,7 +287,7 @@ export class SourceControlImportService {
|
|||
);
|
||||
if (!existingSharedWorkflowOwnerByUserId && !existingSharedWorkflowOwnerByRoleId) {
|
||||
// no owner exists yet, so create one
|
||||
await Db.collections.SharedWorkflow.insert({
|
||||
await Container.get(SharedWorkflowRepository).insert({
|
||||
workflowId: importedWorkflow.id,
|
||||
userId: workflowOwnerId,
|
||||
roleId: ownerWorkflowRole.id,
|
||||
|
@ -288,7 +297,7 @@ export class SourceControlImportService {
|
|||
} else if (existingSharedWorkflowOwnerByUserId && !existingSharedWorkflowOwnerByRoleId) {
|
||||
// if the worklflow has a non-global owner that is referenced by the owner file,
|
||||
// and no existing global owner, update the owner to the user referenced in the owner file
|
||||
await Db.collections.SharedWorkflow.update(
|
||||
await Container.get(SharedWorkflowRepository).update(
|
||||
{
|
||||
workflowId: importedWorkflow.id,
|
||||
userId: workflowOwnerId,
|
||||
|
@ -310,7 +319,7 @@ export class SourceControlImportService {
|
|||
} catch (error) {
|
||||
this.logger.error(`Failed to activate workflow ${existingWorkflow.id}`, error as Error);
|
||||
} finally {
|
||||
await Db.collections.Workflow.update(
|
||||
await Container.get(WorkflowRepository).update(
|
||||
{ id: existingWorkflow.id },
|
||||
{ versionId: importedWorkflow.versionId },
|
||||
);
|
||||
|
@ -331,7 +340,7 @@ export class SourceControlImportService {
|
|||
|
||||
public async importCredentialsFromWorkFolder(candidates: SourceControlledFile[], userId: string) {
|
||||
const candidateIds = candidates.map((c) => c.id);
|
||||
const existingCredentials = await Db.collections.Credentials.find({
|
||||
const existingCredentials = await Container.get(CredentialsRepository).find({
|
||||
where: {
|
||||
id: In(candidateIds),
|
||||
},
|
||||
|
@ -339,7 +348,7 @@ export class SourceControlImportService {
|
|||
});
|
||||
const ownerCredentialRole = await this.getCredentialOwnerRole();
|
||||
const ownerGlobalRole = await this.getOwnerGlobalRole();
|
||||
const existingSharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
const existingSharedCredentials = await Container.get(SharedCredentialsRepository).find({
|
||||
select: ['userId', 'credentialsId', 'roleId'],
|
||||
where: {
|
||||
credentialsId: In(candidateIds),
|
||||
|
@ -370,7 +379,7 @@ export class SourceControlImportService {
|
|||
newCredentialObject.nodesAccess = nodesAccess || existingCredential?.nodesAccess || [];
|
||||
|
||||
this.logger.debug(`Updating credential id ${newCredentialObject.id as string}`);
|
||||
await Db.collections.Credentials.upsert(newCredentialObject, ['id']);
|
||||
await Container.get(CredentialsRepository).upsert(newCredentialObject, ['id']);
|
||||
|
||||
if (!sharedOwner) {
|
||||
const newSharedCredential = new SharedCredentials();
|
||||
|
@ -378,7 +387,7 @@ export class SourceControlImportService {
|
|||
newSharedCredential.userId = userId;
|
||||
newSharedCredential.roleId = ownerCredentialRole.id;
|
||||
|
||||
await Db.collections.SharedCredentials.upsert({ ...newSharedCredential }, [
|
||||
await Container.get(SharedCredentialsRepository).upsert({ ...newSharedCredential }, [
|
||||
'credentialsId',
|
||||
'userId',
|
||||
]);
|
||||
|
@ -413,7 +422,7 @@ export class SourceControlImportService {
|
|||
|
||||
const existingWorkflowIds = new Set(
|
||||
(
|
||||
await Db.collections.Workflow.find({
|
||||
await Container.get(WorkflowRepository).find({
|
||||
select: ['id'],
|
||||
})
|
||||
).map((e) => e.id),
|
||||
|
@ -442,7 +451,7 @@ export class SourceControlImportService {
|
|||
await Promise.all(
|
||||
mappedTags.mappings.map(async (mapping) => {
|
||||
if (!existingWorkflowIds.has(String(mapping.workflowId))) return;
|
||||
await Db.collections.WorkflowTagMapping.upsert(
|
||||
await Container.get(WorkflowTagMappingRepository).upsert(
|
||||
{ tagId: String(mapping.tagId), workflowId: String(mapping.workflowId) },
|
||||
{
|
||||
skipUpdateIfNoValuesChanged: true,
|
||||
|
@ -489,12 +498,12 @@ export class SourceControlImportService {
|
|||
overriddenKeys.splice(overriddenKeys.indexOf(variable.key), 1);
|
||||
}
|
||||
try {
|
||||
await Db.collections.Variables.upsert({ ...variable }, ['id']);
|
||||
await Container.get(VariablesRepository).upsert({ ...variable }, ['id']);
|
||||
} catch (errorUpsert) {
|
||||
if (isUniqueConstraintError(errorUpsert as Error)) {
|
||||
this.logger.debug(`Variable ${variable.key} already exists, updating instead`);
|
||||
try {
|
||||
await Db.collections.Variables.update({ key: variable.key }, { ...variable });
|
||||
await Container.get(VariablesRepository).update({ key: variable.key }, { ...variable });
|
||||
} catch (errorUpdate) {
|
||||
this.logger.debug(`Failed to update variable ${variable.key}, skipping`);
|
||||
this.logger.debug((errorUpdate as Error).message);
|
||||
|
@ -509,8 +518,11 @@ export class SourceControlImportService {
|
|||
if (overriddenKeys.length > 0 && valueOverrides) {
|
||||
for (const key of overriddenKeys) {
|
||||
result.imported.push(key);
|
||||
const newVariable = Db.collections.Variables.create({ key, value: valueOverrides[key] });
|
||||
await Db.collections.Variables.save(newVariable);
|
||||
const newVariable = Container.get(VariablesRepository).create({
|
||||
key,
|
||||
value: valueOverrides[key],
|
||||
});
|
||||
await Container.get(VariablesRepository).save(newVariable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Service } from 'typedi';
|
||||
import Container, { Service } from 'typedi';
|
||||
import { SourceControlPreferences } from './types/sourceControlPreferences';
|
||||
import type { ValidationError } from 'class-validator';
|
||||
import { validate } from 'class-validator';
|
||||
|
@ -11,7 +11,6 @@ import {
|
|||
} from './sourceControlHelper.ee';
|
||||
import { InstanceSettings } from 'n8n-core';
|
||||
import { jsonParse } from 'n8n-workflow';
|
||||
import * as Db from '@/Db';
|
||||
import {
|
||||
SOURCE_CONTROL_SSH_FOLDER,
|
||||
SOURCE_CONTROL_GIT_FOLDER,
|
||||
|
@ -22,6 +21,7 @@ import path from 'path';
|
|||
import type { KeyPairType } from './types/keyPairType';
|
||||
import config from '@/config';
|
||||
import { Logger } from '@/Logger';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
|
||||
@Service()
|
||||
export class SourceControlPreferencesService {
|
||||
|
@ -171,7 +171,7 @@ export class SourceControlPreferencesService {
|
|||
if (saveToDb) {
|
||||
const settingsValue = JSON.stringify(this._sourceControlPreferences);
|
||||
try {
|
||||
await Db.collections.Settings.save({
|
||||
await Container.get(SettingsRepository).save({
|
||||
key: SOURCE_CONTROL_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
|
@ -186,7 +186,7 @@ export class SourceControlPreferencesService {
|
|||
async loadFromDbAndApplySourceControlPreferences(): Promise<
|
||||
SourceControlPreferences | undefined
|
||||
> {
|
||||
const loadedPreferences = await Db.collections.Settings.findOne({
|
||||
const loadedPreferences = await Container.get(SettingsRepository).findOne({
|
||||
where: { key: SOURCE_CONTROL_PREFERENCES_DB_KEY },
|
||||
});
|
||||
if (loadedPreferences) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { Variables } from '@db/entities/Variables';
|
||||
import { CacheService } from '@/services/cache.service';
|
||||
import Container, { Service } from 'typedi';
|
||||
import { VariablesRepository } from '@/databases/repositories';
|
||||
import { VariablesRepository } from '@db/repositories/variables.repository';
|
||||
import type { DeepPartial } from 'typeorm';
|
||||
|
||||
@Service()
|
||||
|
|
|
@ -11,7 +11,6 @@ import type { MessageEventBusDestination } from '../MessageEventBusDestination/M
|
|||
import { MessageEventBusLogWriter } from '../MessageEventBusWriter/MessageEventBusLogWriter';
|
||||
import EventEmitter from 'events';
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import { messageEventBusDestinationFromDb } from '../MessageEventBusDestination/MessageEventBusDestinationFromDb';
|
||||
import uniqby from 'lodash/uniqBy';
|
||||
import type { EventMessageConfirmSource } from '../EventMessageClasses/EventMessageConfirm';
|
||||
|
@ -29,11 +28,13 @@ import {
|
|||
import { recoverExecutionDataFromEventLogMessages } from './recoverEvents';
|
||||
import { METRICS_EVENT_NAME } from '../MessageEventBusDestination/Helpers.ee';
|
||||
import { Container, Service } from 'typedi';
|
||||
import { ExecutionRepository, WorkflowRepository } from '@/databases/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import type { AbstractEventMessageOptions } from '../EventMessageClasses/AbstractEventMessageOptions';
|
||||
import { getEventMessageObjectByType } from '../EventMessageClasses/Helpers';
|
||||
import { SingleMainInstancePublisher } from '@/services/orchestration/main/SingleMainInstance.publisher';
|
||||
import { Logger } from '@/Logger';
|
||||
import { EventDestinationsRepository } from '@db/repositories/eventDestinations.repository';
|
||||
|
||||
export type EventMessageReturnMode = 'sent' | 'unsent' | 'all' | 'unfinished';
|
||||
|
||||
|
@ -79,7 +80,7 @@ export class MessageEventBus extends EventEmitter {
|
|||
|
||||
this.logger.debug('Initializing event bus...');
|
||||
|
||||
const savedEventDestinations = await Db.collections.EventDestinations.find({});
|
||||
const savedEventDestinations = await Container.get(EventDestinationsRepository).find({});
|
||||
if (savedEventDestinations.length > 0) {
|
||||
for (const destinationData of savedEventDestinations) {
|
||||
try {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Push } from '@/push';
|
|||
import { Container } from 'typedi';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { getWorkflowHooksMain } from '@/WorkflowExecuteAdditionalData';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
|
||||
export async function recoverExecutionDataFromEventLogMessages(
|
||||
executionId: string,
|
||||
|
|
|
@ -6,13 +6,13 @@ import {
|
|||
MessageEventBusDestinationTypeNames,
|
||||
MessageEventBusDestinationOptions,
|
||||
} from 'n8n-workflow';
|
||||
import * as Db from '@/Db';
|
||||
import { Logger } from '@/Logger';
|
||||
import type { AbstractEventMessage } from '../EventMessageClasses/AbstractEventMessage';
|
||||
import type { EventMessageTypes } from '../EventMessageClasses';
|
||||
import type { EventMessageConfirmSource } from '../EventMessageClasses/EventMessageConfirm';
|
||||
import { MessageEventBus } from '../MessageEventBus/MessageEventBus';
|
||||
import type { MessageWithCallback } from '../MessageEventBus/MessageEventBus';
|
||||
import { EventDestinationsRepository } from '@db/repositories/eventDestinations.repository';
|
||||
|
||||
export abstract class MessageEventBusDestination implements MessageEventBusDestinationOptions {
|
||||
// Since you can't have static abstract functions - this just serves as a reminder that you need to implement these. Please.
|
||||
|
@ -96,7 +96,7 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
|
|||
id: this.getId(),
|
||||
destination: this.serialize(),
|
||||
};
|
||||
const dbResult: InsertResult = await Db.collections.EventDestinations.upsert(data, {
|
||||
const dbResult: InsertResult = await Container.get(EventDestinationsRepository).upsert(data, {
|
||||
skipUpdateIfNoValuesChanged: true,
|
||||
conflictPaths: ['id'],
|
||||
});
|
||||
|
@ -108,7 +108,7 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
|
|||
}
|
||||
|
||||
static async deleteFromDb(id: string): Promise<DeleteResult> {
|
||||
const dbResult = await Db.collections.EventDestinations.delete({ id });
|
||||
const dbResult = await Container.get(EventDestinationsRepository).delete({ id });
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { MessageEventBusDestinationTypeNames } from 'n8n-workflow';
|
||||
import type { EventDestinations } from '@/databases/entities/EventDestinations';
|
||||
import type { EventDestinations } from '@db/entities/EventDestinations';
|
||||
import type { MessageEventBus } from '../MessageEventBus/MessageEventBus';
|
||||
import type { MessageEventBusDestination } from './MessageEventBusDestination.ee';
|
||||
import { MessageEventBusDestinationSentry } from './MessageEventBusDestinationSentry.ee';
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { ExecutionStatus, IRun, IWorkflowBase } from 'n8n-workflow';
|
|||
import type { ExecutionPayload, IExecutionDb } from '@/Interfaces';
|
||||
import pick from 'lodash/pick';
|
||||
import { isWorkflowIdValid } from '@/utils';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { ExecutionMetadataService } from '@/services/executionMetadata.service';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ import type { ExecutionRequest } from '@/requests';
|
|||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import { getSharedWorkflowIds } from '@/WorkflowHelpers';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import * as Db from '@/Db';
|
||||
import * as GenericHelpers from '@/GenericHelpers';
|
||||
import { Container } from 'typedi';
|
||||
import { getStatusUsingPreviousExecutionStatusMethod } from './executionHelpers';
|
||||
import { ExecutionRepository } from '@db/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
|
||||
export interface IGetExecutionsQueryFilter {
|
||||
|
@ -274,7 +274,7 @@ export class ExecutionsService {
|
|||
// Loads the currently saved workflow to execute instead of the
|
||||
// one saved at the time of the execution.
|
||||
const workflowId = execution.workflowData.id as string;
|
||||
const workflowData = (await Db.collections.Workflow.findOneBy({
|
||||
const workflowData = (await Container.get(WorkflowRepository).findOneBy({
|
||||
id: workflowId,
|
||||
})) as IWorkflowBase;
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { Container } from 'typedi';
|
||||
import { License } from '@/License';
|
||||
import type { ILicenseReadResponse } from '@/Interfaces';
|
||||
import * as Db from '@/Db';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
export class LicenseService {
|
||||
static async getActiveTriggerCount(): Promise<number> {
|
||||
const totalTriggerCount = await Db.collections.Workflow.sum('triggerCount', { active: true });
|
||||
const totalTriggerCount = await Container.get(WorkflowRepository).sum('triggerCount', {
|
||||
active: true,
|
||||
});
|
||||
return totalTriggerCount ?? 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { EventEmitter } from 'events';
|
|||
import { assert, jsonStringify } from 'n8n-workflow';
|
||||
import type { IPushDataType } from '@/Interfaces';
|
||||
import { Logger } from '@/Logger';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
||||
/**
|
||||
* Abstract class for two-way push communication.
|
||||
|
|
|
@ -13,7 +13,7 @@ import { SSEPush } from './sse.push';
|
|||
import { WebSocketPush } from './websocket.push';
|
||||
import type { PushResponse, SSEPushRequest, WebSocketPushRequest } from './types';
|
||||
import type { IPushDataType } from '@/Interfaces';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
||||
const useWebSockets = config.getEnv('push.backend') === 'websocket';
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Service } from 'typedi';
|
|||
import { Logger } from '@/Logger';
|
||||
import { AbstractPush } from './abstract.push';
|
||||
import type { PushRequest, PushResponse } from './types';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
||||
type Connection = { req: PushRequest; res: PushResponse };
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type { Request, Response } from 'express';
|
||||
import type { WebSocket } from 'ws';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import type WebSocket from 'ws';
|
|||
import { Service } from 'typedi';
|
||||
import { Logger } from '@/Logger';
|
||||
import { AbstractPush } from './abstract.push';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { User } from '@db/entities/User';
|
||||
|
||||
function heartbeat(this: WebSocket) {
|
||||
this.isAlive = true;
|
||||
|
|
|
@ -26,9 +26,9 @@ import type { Role } from '@db/entities/Role';
|
|||
import type { User } from '@db/entities/User';
|
||||
import type { UserManagementMailer } from '@/UserManagement/email';
|
||||
import type { Variables } from '@db/entities/Variables';
|
||||
import type { WorkflowEntity } from './databases/entities/WorkflowEntity';
|
||||
import type { CredentialsEntity } from './databases/entities/CredentialsEntity';
|
||||
import type { WorkflowHistory } from './databases/entities/WorkflowHistory';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import type { WorkflowHistory } from '@db/entities/WorkflowHistory';
|
||||
|
||||
export class UserUpdatePayload implements Pick<User, 'email' | 'firstName' | 'lastName'> {
|
||||
@IsEmail()
|
||||
|
|
|
@ -10,8 +10,8 @@ import { InstanceSettings } from 'n8n-core';
|
|||
import type { PackageDirectoryLoader } from 'n8n-core';
|
||||
|
||||
import { toError } from '@/utils';
|
||||
import { InstalledPackagesRepository } from '@/databases/repositories/installedPackages.repository';
|
||||
import type { InstalledPackages } from '@/databases/entities/InstalledPackages';
|
||||
import { InstalledPackagesRepository } from '@db/repositories/installedPackages.repository';
|
||||
import type { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||
import {
|
||||
NODE_PACKAGE_PREFIX,
|
||||
NPM_COMMAND_TOKENS,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { EventEmitter } from 'events';
|
|||
import { Container, Service } from 'typedi';
|
||||
import type { INode, IRun, IWorkflowBase } from 'n8n-workflow';
|
||||
import { StatisticsNames } from '@db/entities/WorkflowStatistics';
|
||||
import { WorkflowStatisticsRepository } from '@db/repositories';
|
||||
import { WorkflowStatisticsRepository } from '@db/repositories/workflowStatistics.repository';
|
||||
import { UserService } from '@/services/user.service';
|
||||
import { Logger } from '@/Logger';
|
||||
import { OwnershipService } from './ownership.service';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ExecutionMetadataRepository } from '@/databases/repositories';
|
||||
import { Service } from 'typedi';
|
||||
import type { ExecutionMetadata } from '@/databases/entities/ExecutionMetadata';
|
||||
import { ExecutionMetadataRepository } from '@db/repositories/executionMetadata.repository';
|
||||
import type { ExecutionMetadata } from '@db/entities/ExecutionMetadata';
|
||||
|
||||
@Service()
|
||||
export class ExecutionMetadataService {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Service } from 'typedi';
|
||||
import { CacheService } from './cache.service';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import type { User } from '@db/entities/User';
|
||||
import { RoleService } from './role.service';
|
||||
import { UserService } from './user.service';
|
||||
import type { Credentials, ListQuery } from '@/requests';
|
||||
import type { Role } from '@/databases/entities/Role';
|
||||
import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
|
||||
import type { Role } from '@db/entities/Role';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
|
||||
@Service()
|
||||
export class OwnershipService {
|
||||
|
|
|
@ -6,9 +6,9 @@ import type { FindOptionsWhere } from 'typeorm';
|
|||
|
||||
import { TIME, inTest } from '@/constants';
|
||||
import config from '@/config';
|
||||
import { ExecutionRepository } from '@/databases/repositories';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { Logger } from '@/Logger';
|
||||
import { ExecutionEntity } from '@/databases/entities/ExecutionEntity';
|
||||
import { ExecutionEntity } from '@db/entities/ExecutionEntity';
|
||||
|
||||
@Service()
|
||||
export class PruningService {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { RoleRepository, SharedWorkflowRepository } from '@/databases/repositories';
|
||||
import { Service } from 'typedi';
|
||||
import { RoleRepository } from '@db/repositories/role.repository';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { CacheService } from './cache.service';
|
||||
import type { RoleNames, RoleScopes } from '@/databases/entities/Role';
|
||||
import type { RoleNames, RoleScopes } from '@db/entities/Role';
|
||||
|
||||
class InvalidRoleError extends Error {}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { TagRepository } from '@/databases/repositories';
|
||||
import { TagRepository } from '@db/repositories/tag.repository';
|
||||
import { Service } from 'typedi';
|
||||
import { validateEntity } from '@/GenericHelpers';
|
||||
import type { ITagToImport, ITagWithCountDb, IWorkflowToImport } from '@/Interfaces';
|
||||
import type { TagEntity } from '@/databases/entities/TagEntity';
|
||||
import type { TagEntity } from '@db/entities/TagEntity';
|
||||
import type { EntityManager, FindManyOptions, FindOneOptions } from 'typeorm';
|
||||
import type { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
||||
import { ExternalHooks } from '@/ExternalHooks';
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere }
|
|||
import { In } from 'typeorm';
|
||||
import { User } from '@db/entities/User';
|
||||
import type { IUserSettings } from 'n8n-workflow';
|
||||
import { UserRepository } from '@/databases/repositories';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';
|
||||
import type { PublicUser } from '@/Interfaces';
|
||||
import type { PostHogClient } from '@/posthog';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { WebhookRepository } from '@/databases/repositories';
|
||||
import { WebhookRepository } from '@db/repositories/webhook.repository';
|
||||
import { Service } from 'typedi';
|
||||
import { CacheService } from './cache.service';
|
||||
import type { WebhookEntity } from '@/databases/entities/WebhookEntity';
|
||||
import type { WebhookEntity } from '@db/entities/WebhookEntity';
|
||||
import type { IHttpRequestMethods } from 'n8n-workflow';
|
||||
import type { DeepPartial } from 'typeorm';
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type express from 'express';
|
||||
import { Service } from 'typedi';
|
||||
import * as Db from '@/Db';
|
||||
import Container, { Service } from 'typedi';
|
||||
import type { User } from '@db/entities/User';
|
||||
import { jsonParse } from 'n8n-workflow';
|
||||
import { AuthError, BadRequestError } from '@/ResponseHelper';
|
||||
|
@ -28,6 +27,8 @@ import type { SamlLoginBinding } from './types';
|
|||
import { validateMetadata, validateResponse } from './samlValidator';
|
||||
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';
|
||||
import { Logger } from '@/Logger';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
|
||||
@Service()
|
||||
export class SamlService {
|
||||
|
@ -167,7 +168,7 @@ export class SamlService {
|
|||
const attributes = await this.getAttributesFromLoginResponse(req, binding);
|
||||
if (attributes.email) {
|
||||
const lowerCasedEmail = attributes.email.toLowerCase();
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Container.get(UserRepository).findOne({
|
||||
where: { email: lowerCasedEmail },
|
||||
relations: ['globalRole', 'authIdentities'],
|
||||
});
|
||||
|
@ -257,7 +258,7 @@ export class SamlService {
|
|||
}
|
||||
|
||||
async loadFromDbAndApplySamlPreferences(apply = true): Promise<SamlPreferences | undefined> {
|
||||
const samlPreferences = await Db.collections.Settings.findOne({
|
||||
const samlPreferences = await Container.get(SettingsRepository).findOne({
|
||||
where: { key: SAML_PREFERENCES_DB_KEY },
|
||||
});
|
||||
if (samlPreferences) {
|
||||
|
@ -275,16 +276,16 @@ export class SamlService {
|
|||
}
|
||||
|
||||
async saveSamlPreferencesToDb(): Promise<SamlPreferences | undefined> {
|
||||
const samlPreferences = await Db.collections.Settings.findOne({
|
||||
const samlPreferences = await Container.get(SettingsRepository).findOne({
|
||||
where: { key: SAML_PREFERENCES_DB_KEY },
|
||||
});
|
||||
const settingsValue = JSON.stringify(this.samlPreferences);
|
||||
let result: Settings;
|
||||
if (samlPreferences) {
|
||||
samlPreferences.value = settingsValue;
|
||||
result = await Db.collections.Settings.save(samlPreferences);
|
||||
result = await Container.get(SettingsRepository).save(samlPreferences);
|
||||
} else {
|
||||
result = await Db.collections.Settings.save({
|
||||
result = await Container.get(SettingsRepository).save({
|
||||
key: SAML_PREFERENCES_DB_KEY,
|
||||
value: settingsValue,
|
||||
loadOnStartup: true,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Container } from 'typedi';
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import { AuthIdentity } from '@db/entities/AuthIdentity';
|
||||
import { User } from '@db/entities/User';
|
||||
import { License } from '@/License';
|
||||
|
@ -20,6 +19,8 @@ import {
|
|||
import { getServiceProviderConfigTestReturnUrl } from './serviceProvider.ee';
|
||||
import type { SamlConfiguration } from './types/requests';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { UserRepository } from '@db/repositories/user.repository';
|
||||
import { AuthIdentityRepository } from '@db/repositories/authIdentity.repository';
|
||||
/**
|
||||
* Check whether the SAML feature is licensed and enabled in the instance
|
||||
*/
|
||||
|
@ -107,10 +108,10 @@ export async function createUserFromSamlAttributes(attributes: SamlUserAttribute
|
|||
authIdentity.providerId = attributes.userPrincipalName;
|
||||
authIdentity.providerType = 'saml';
|
||||
authIdentity.user = user;
|
||||
const resultAuthIdentity = await Db.collections.AuthIdentity.save(authIdentity);
|
||||
const resultAuthIdentity = await Container.get(AuthIdentityRepository).save(authIdentity);
|
||||
if (!resultAuthIdentity) throw new AuthError('Could not create AuthIdentity');
|
||||
user.authIdentities = [authIdentity];
|
||||
const resultUser = await Db.collections.User.save(user);
|
||||
const resultUser = await Container.get(UserRepository).save(user);
|
||||
if (!resultUser) throw new AuthError('Could not create User');
|
||||
return resultUser;
|
||||
}
|
||||
|
@ -131,10 +132,10 @@ export async function updateUserFromSamlAttributes(
|
|||
} else {
|
||||
samlAuthIdentity.providerId = attributes.userPrincipalName;
|
||||
}
|
||||
await Db.collections.AuthIdentity.save(samlAuthIdentity);
|
||||
await Container.get(AuthIdentityRepository).save(samlAuthIdentity);
|
||||
user.firstName = attributes.firstName;
|
||||
user.lastName = attributes.lastName;
|
||||
const resultUser = await Db.collections.User.save(user);
|
||||
const resultUser = await Container.get(UserRepository).save(user);
|
||||
if (!resultUser) throw new AuthError('Could not create User');
|
||||
return resultUser;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import type { AuthProviderType } from '@db/entities/AuthIdentity';
|
||||
import Container from 'typedi';
|
||||
|
||||
/**
|
||||
* Only one authentication method can be active at a time. This function sets the current authentication method
|
||||
|
@ -12,7 +13,7 @@ export async function setCurrentAuthenticationMethod(
|
|||
authenticationMethod: AuthProviderType,
|
||||
): Promise<void> {
|
||||
config.set('userManagement.authenticationMethod', authenticationMethod);
|
||||
await Db.collections.Settings.save({
|
||||
await Container.get(SettingsRepository).save({
|
||||
key: 'userManagement.authenticationMethod',
|
||||
value: authenticationMethod,
|
||||
loadOnStartup: true,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import type { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { WorkflowEntity } from '@/databases/entities/WorkflowEntity';
|
||||
import type { WorkflowHistory } from '@/databases/entities/WorkflowHistory';
|
||||
import { SharedWorkflowRepository } from '@/databases/repositories';
|
||||
import type { SharedWorkflow } from '@db/entities/SharedWorkflow';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
|
||||
import type { WorkflowHistory } from '@db/entities/WorkflowHistory';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
|
||||
import { Service } from 'typedi';
|
||||
import { isWorkflowHistoryEnabled } from './workflowHistoryHelper.ee';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Service } from 'typedi';
|
||||
import { LessThan } from 'typeorm';
|
||||
import { DateTime } from 'luxon';
|
||||
import { WorkflowHistoryRepository } from '@/databases/repositories';
|
||||
import { WorkflowHistoryRepository } from '@db/repositories/workflowHistory.repository';
|
||||
import { WORKFLOW_HISTORY_PRUNE_INTERVAL } from './constants';
|
||||
import { getWorkflowHistoryPruneTime, isWorkflowHistoryEnabled } from './workflowHistoryHelper.ee';
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import { listQueryMiddleware } from '@/middlewares';
|
|||
import { TagService } from '@/services/tag.service';
|
||||
import { WorkflowHistoryService } from './workflowHistory/workflowHistory.service.ee';
|
||||
import { Logger } from '@/Logger';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
|
||||
export const workflowsController = express.Router();
|
||||
workflowsController.use('/', EEWorkflowController);
|
||||
|
@ -205,7 +206,7 @@ workflowsController.get(
|
|||
relations = relations.filter((relation) => relation !== 'workflow.tags');
|
||||
}
|
||||
|
||||
const shared = await Db.collections.SharedWorkflow.findOne({
|
||||
const shared = await Container.get(SharedWorkflowRepository).findOne({
|
||||
relations,
|
||||
where: whereClause({
|
||||
user: req.user,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { DeleteResult, EntityManager } from 'typeorm';
|
||||
import { In, Not } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import * as WorkflowHelpers from '@/WorkflowHelpers';
|
||||
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
|
||||
|
@ -16,7 +15,8 @@ import { CredentialsService } from '@/credentials/credentials.service';
|
|||
import { NodeOperationError } from 'n8n-workflow';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import Container from 'typedi';
|
||||
import type { CredentialsEntity } from '@/databases/entities/CredentialsEntity';
|
||||
import type { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
|
||||
export class EEWorkflowsService extends WorkflowsService {
|
||||
static async isOwned(
|
||||
|
@ -73,7 +73,7 @@ export class EEWorkflowsService extends WorkflowsService {
|
|||
userId: user.id,
|
||||
roleId: role?.id,
|
||||
};
|
||||
acc.push(Db.collections.SharedWorkflow.create(entity));
|
||||
acc.push(Container.get(SharedWorkflowRepository).create(entity));
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import { In, Like } from 'typeorm';
|
|||
import pick from 'lodash/pick';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||
import * as Db from '@/Db';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import * as WorkflowHelpers from '@/WorkflowHelpers';
|
||||
import config from '@/config';
|
||||
|
@ -24,13 +23,16 @@ import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData'
|
|||
import { TestWebhooks } from '@/TestWebhooks';
|
||||
import { whereClause } from '@/UserManagement/UserManagementHelper';
|
||||
import { InternalHooks } from '@/InternalHooks';
|
||||
import { WorkflowRepository } from '@/databases/repositories';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import { RoleService } from '@/services/role.service';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { isStringArray, isWorkflowIdValid } from '@/utils';
|
||||
import { WorkflowHistoryService } from './workflowHistory/workflowHistory.service.ee';
|
||||
import { BinaryDataService } from 'n8n-core';
|
||||
import { Logger } from '@/Logger';
|
||||
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
||||
import { WorkflowTagMappingRepository } from '@db/repositories/workflowTagMapping.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
|
||||
export class WorkflowsService {
|
||||
static async getSharing(
|
||||
|
@ -48,7 +50,7 @@ export class WorkflowsService {
|
|||
where.userId = user.id;
|
||||
}
|
||||
|
||||
return Db.collections.SharedWorkflow.findOne({ where, relations });
|
||||
return Container.get(SharedWorkflowRepository).findOne({ where, relations });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +96,10 @@ export class WorkflowsService {
|
|||
}
|
||||
|
||||
static async get(workflow: FindOptionsWhere<WorkflowEntity>, options?: { relations: string[] }) {
|
||||
return Db.collections.Workflow.findOne({ where: workflow, relations: options?.relations });
|
||||
return Container.get(WorkflowRepository).findOne({
|
||||
where: workflow,
|
||||
relations: options?.relations,
|
||||
});
|
||||
}
|
||||
|
||||
static async getMany(sharedWorkflowIds: string[], options?: ListQuery.Options) {
|
||||
|
@ -186,7 +191,7 @@ export class WorkflowsService {
|
|||
forceSave?: boolean,
|
||||
roles?: string[],
|
||||
): Promise<WorkflowEntity> {
|
||||
const shared = await Db.collections.SharedWorkflow.findOne({
|
||||
const shared = await Container.get(SharedWorkflowRepository).findOne({
|
||||
relations: ['workflow', 'role'],
|
||||
where: whereClause({
|
||||
user,
|
||||
|
@ -282,7 +287,7 @@ export class WorkflowsService {
|
|||
await validateEntity(workflow);
|
||||
}
|
||||
|
||||
await Db.collections.Workflow.update(
|
||||
await Container.get(WorkflowRepository).update(
|
||||
workflowId,
|
||||
pick(workflow, [
|
||||
'name',
|
||||
|
@ -297,8 +302,8 @@ export class WorkflowsService {
|
|||
);
|
||||
|
||||
if (tagIds && !config.getEnv('workflowTagsDisabled')) {
|
||||
await Db.collections.WorkflowTagMapping.delete({ workflowId });
|
||||
await Db.collections.WorkflowTagMapping.insert(
|
||||
await Container.get(WorkflowTagMappingRepository).delete({ workflowId });
|
||||
await Container.get(WorkflowTagMappingRepository).insert(
|
||||
tagIds.map((tagId) => ({ tagId, workflowId })),
|
||||
);
|
||||
}
|
||||
|
@ -311,7 +316,7 @@ export class WorkflowsService {
|
|||
|
||||
// We sadly get nothing back from "update". Neither if it updated a record
|
||||
// nor the new value. So query now the hopefully updated entry.
|
||||
const updatedWorkflow = await Db.collections.Workflow.findOne({
|
||||
const updatedWorkflow = await Container.get(WorkflowRepository).findOne({
|
||||
where: { id: workflowId },
|
||||
relations,
|
||||
});
|
||||
|
@ -342,7 +347,7 @@ export class WorkflowsService {
|
|||
} catch (error) {
|
||||
// If workflow could not be activated set it again to inactive
|
||||
// and revert the versionId change so UI remains consistent
|
||||
await Db.collections.Workflow.update(workflowId, {
|
||||
await Container.get(WorkflowRepository).update(workflowId, {
|
||||
active: false,
|
||||
versionId: shared.workflow.versionId,
|
||||
});
|
||||
|
@ -447,7 +452,7 @@ export class WorkflowsService {
|
|||
static async delete(user: User, workflowId: string): Promise<WorkflowEntity | undefined> {
|
||||
await Container.get(ExternalHooks).run('workflow.delete', [workflowId]);
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
const sharedWorkflow = await Container.get(SharedWorkflowRepository).findOne({
|
||||
relations: ['workflow', 'role'],
|
||||
where: whereClause({
|
||||
user,
|
||||
|
@ -466,12 +471,14 @@ export class WorkflowsService {
|
|||
await Container.get(ActiveWorkflowRunner).remove(workflowId);
|
||||
}
|
||||
|
||||
const idsForDeletion = await Db.collections.Execution.find({
|
||||
select: ['id'],
|
||||
where: { workflowId },
|
||||
}).then((rows) => rows.map(({ id: executionId }) => ({ workflowId, executionId })));
|
||||
const idsForDeletion = await Container.get(ExecutionRepository)
|
||||
.find({
|
||||
select: ['id'],
|
||||
where: { workflowId },
|
||||
})
|
||||
.then((rows) => rows.map(({ id: executionId }) => ({ workflowId, executionId })));
|
||||
|
||||
await Db.collections.Workflow.delete(workflowId);
|
||||
await Container.get(WorkflowRepository).delete(workflowId);
|
||||
await Container.get(BinaryDataService).deleteMany(idsForDeletion);
|
||||
|
||||
void Container.get(InternalHooks).onWorkflowDeleted(user, workflowId, false);
|
||||
|
@ -481,7 +488,7 @@ export class WorkflowsService {
|
|||
}
|
||||
|
||||
static async updateWorkflowTriggerCount(id: string, triggerCount: number): Promise<UpdateResult> {
|
||||
const qb = Db.collections.Workflow.createQueryBuilder('workflow');
|
||||
const qb = Container.get(WorkflowRepository).createQueryBuilder('workflow');
|
||||
return qb
|
||||
.update()
|
||||
.set({
|
||||
|
@ -527,7 +534,7 @@ export class WorkflowsService {
|
|||
* @param {IDataObject} newStaticData The static data to save
|
||||
*/
|
||||
static async saveStaticDataById(workflowId: string, newStaticData: IDataObject): Promise<void> {
|
||||
await Db.collections.Workflow.update(workflowId, {
|
||||
await Container.get(WorkflowRepository).update(workflowId, {
|
||||
staticData: newStaticData,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,14 +14,15 @@ import { WebhookService } from '@/services/webhook.service';
|
|||
import * as WebhookHelpers from '@/WebhookHelpers';
|
||||
import * as AdditionalData from '@/WorkflowExecuteAdditionalData';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
|
||||
import { mockInstance, setSchedulerAsLoadedNode } from './shared/utils';
|
||||
import * as testDb from './shared/testDb';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
import type { WebhookEntity } from '@/databases/entities/WebhookEntity';
|
||||
import type { User } from '@db/entities/User';
|
||||
import type { WebhookEntity } from '@db/entities/WebhookEntity';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { chooseRandomly } from './shared/random';
|
||||
import { MultiMainInstancePublisher } from '@/services/orchestration/main/MultiMainInstance.publisher.ee';
|
||||
|
||||
import { mockInstance } from '../shared/mocking';
|
||||
import { chooseRandomly } from './shared/random';
|
||||
import { setSchedulerAsLoadedNode } from './shared/utils';
|
||||
import * as testDb from './shared/testDb';
|
||||
import { createOwner } from './shared/db/users';
|
||||
import { createWorkflow } from './shared/db/workflows';
|
||||
|
||||
|
|
|
@ -1,36 +1,38 @@
|
|||
import type { SuperAgentTest } from 'supertest';
|
||||
import { License } from '@/License';
|
||||
import * as utils from '../shared/utils/';
|
||||
import type { ExternalSecretsSettings, SecretsProviderState } from '@/Interfaces';
|
||||
import { Cipher } from 'n8n-core';
|
||||
import { SettingsRepository } from '@/databases/repositories/settings.repository';
|
||||
import { SettingsRepository } from '@db/repositories/settings.repository';
|
||||
import { Container } from 'typedi';
|
||||
import { ExternalSecretsProviders } from '@/ExternalSecrets/ExternalSecretsProviders.ee';
|
||||
import config from '@/config';
|
||||
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
|
||||
import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
|
||||
import { jsonParse, type IDataObject } from 'n8n-workflow';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
import { setupTestServer } from '../shared/utils';
|
||||
import { createOwner, createUser } from '../shared/db/users';
|
||||
import {
|
||||
DummyProvider,
|
||||
FailedProvider,
|
||||
MockProviders,
|
||||
TestFailProvider,
|
||||
} from '../../shared/ExternalSecrets/utils';
|
||||
import config from '@/config';
|
||||
import { ExternalSecretsManager } from '@/ExternalSecrets/ExternalSecretsManager.ee';
|
||||
import { CREDENTIAL_BLANKING_VALUE } from '@/constants';
|
||||
import { jsonParse, type IDataObject } from 'n8n-workflow';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import { createOwner, createUser } from '../shared/db/users';
|
||||
|
||||
let authOwnerAgent: SuperAgentTest;
|
||||
let authMemberAgent: SuperAgentTest;
|
||||
|
||||
const licenseLike = utils.mockInstance(License, {
|
||||
const licenseLike = mockInstance(License, {
|
||||
isExternalSecretsEnabled: jest.fn().mockReturnValue(true),
|
||||
isWithinUsersLimit: jest.fn().mockReturnValue(true),
|
||||
});
|
||||
|
||||
const mockProvidersInstance = new MockProviders();
|
||||
utils.mockInstance(ExternalSecretsProviders, mockProvidersInstance);
|
||||
mockInstance(ExternalSecretsProviders, mockProvidersInstance);
|
||||
|
||||
const testServer = utils.setupTestServer({ endpointGroups: ['externalSecrets'] });
|
||||
const testServer = setupTestServer({ endpointGroups: ['externalSecrets'] });
|
||||
|
||||
const connectedDate = '2023-08-01T12:32:29.000Z';
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import * as Db from '@/Db';
|
||||
import config from '@/config';
|
||||
import { audit } from '@/audit';
|
||||
import { CREDENTIALS_REPORT } from '@/audit/constants';
|
||||
import { getRiskSection } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
import { CredentialsRepository } from '@db/repositories/credentials.repository';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { ExecutionDataRepository } from '@db/repositories/executionData.repository';
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
@ -46,8 +50,8 @@ test('should report credentials not in any use', async () => {
|
|||
};
|
||||
|
||||
await Promise.all([
|
||||
Db.collections.Credentials.save(credentialDetails),
|
||||
Db.collections.Workflow.save(workflowDetails),
|
||||
Container.get(CredentialsRepository).save(credentialDetails),
|
||||
Container.get(WorkflowRepository).save(workflowDetails),
|
||||
]);
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
|
@ -74,7 +78,7 @@ test('should report credentials not in active use', async () => {
|
|||
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
|
||||
};
|
||||
|
||||
const credential = await Db.collections.Credentials.save(credentialDetails);
|
||||
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
|
||||
|
||||
const workflowDetails = {
|
||||
id: generateNanoId(),
|
||||
|
@ -93,7 +97,7 @@ test('should report credentials not in active use', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
await Db.collections.Workflow.save(workflowDetails);
|
||||
await Container.get(WorkflowRepository).save(workflowDetails);
|
||||
|
||||
const testAudit = await audit(['credentials']);
|
||||
|
||||
|
@ -119,7 +123,7 @@ test('should report credential in not recently executed workflow', async () => {
|
|||
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
|
||||
};
|
||||
|
||||
const credential = await Db.collections.Credentials.save(credentialDetails);
|
||||
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
|
||||
|
||||
const workflowDetails = {
|
||||
id: generateNanoId(),
|
||||
|
@ -144,12 +148,12 @@ test('should report credential in not recently executed workflow', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
const workflow = await Db.collections.Workflow.save(workflowDetails);
|
||||
const workflow = await Container.get(WorkflowRepository).save(workflowDetails);
|
||||
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - config.getEnv('security.audit.daysAbandonedWorkflow') - 1);
|
||||
|
||||
const savedExecution = await Db.collections.Execution.save({
|
||||
const savedExecution = await Container.get(ExecutionRepository).save({
|
||||
finished: true,
|
||||
mode: 'manual',
|
||||
startedAt: date,
|
||||
|
@ -157,7 +161,7 @@ test('should report credential in not recently executed workflow', async () => {
|
|||
workflowId: workflow.id,
|
||||
waitTill: null,
|
||||
});
|
||||
await Db.collections.ExecutionData.save({
|
||||
await Container.get(ExecutionDataRepository).save({
|
||||
execution: savedExecution,
|
||||
data: '[]',
|
||||
workflowData: workflow,
|
||||
|
@ -187,7 +191,7 @@ test('should not report credentials in recently executed workflow', async () =>
|
|||
nodesAccess: [{ nodeType: 'n8n-nodes-base.slack', date: '2022-12-21T11:23:00.561Z' }],
|
||||
};
|
||||
|
||||
const credential = await Db.collections.Credentials.save(credentialDetails);
|
||||
const credential = await Container.get(CredentialsRepository).save(credentialDetails);
|
||||
|
||||
const workflowDetails = {
|
||||
id: generateNanoId(),
|
||||
|
@ -212,12 +216,12 @@ test('should not report credentials in recently executed workflow', async () =>
|
|||
],
|
||||
};
|
||||
|
||||
const workflow = await Db.collections.Workflow.save(workflowDetails);
|
||||
const workflow = await Container.get(WorkflowRepository).save(workflowDetails);
|
||||
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - config.getEnv('security.audit.daysAbandonedWorkflow') + 1);
|
||||
|
||||
const savedExecution = await Db.collections.Execution.save({
|
||||
const savedExecution = await Container.get(ExecutionRepository).save({
|
||||
finished: true,
|
||||
mode: 'manual',
|
||||
startedAt: date,
|
||||
|
@ -226,7 +230,7 @@ test('should not report credentials in recently executed workflow', async () =>
|
|||
waitTill: null,
|
||||
});
|
||||
|
||||
await Db.collections.ExecutionData.save({
|
||||
await Container.get(ExecutionDataRepository).save({
|
||||
execution: savedExecution,
|
||||
data: '[]',
|
||||
workflowData: workflow,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import * as Db from '@/Db';
|
||||
import { audit } from '@/audit';
|
||||
import {
|
||||
DATABASE_REPORT,
|
||||
|
@ -9,6 +8,8 @@ import {
|
|||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
@ -50,7 +51,7 @@ test('should report expressions in queries', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
@ -105,7 +106,7 @@ test('should report expressions in query params', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
@ -157,7 +158,7 @@ test('should report unused query params', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import * as Db from '@/Db';
|
||||
import { audit } from '@/audit';
|
||||
import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/constants';
|
||||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
@ -26,7 +27,7 @@ test('should report filesystem interaction nodes', async () => {
|
|||
);
|
||||
|
||||
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
||||
const details = Db.collections.Workflow.create({
|
||||
const details = Container.get(WorkflowRepository).create({
|
||||
name: 'My Test Workflow',
|
||||
active: false,
|
||||
connections: {},
|
||||
|
@ -42,7 +43,7 @@ test('should report filesystem interaction nodes', async () => {
|
|||
],
|
||||
});
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import * as Db from '@/Db';
|
||||
import { audit } from '@/audit';
|
||||
import { INSTANCE_REPORT, WEBHOOK_VALIDATOR_NODE_TYPES } from '@/audit/constants';
|
||||
import {
|
||||
|
@ -13,6 +12,8 @@ import * as testDb from '../shared/testDb';
|
|||
import { toReportTitle } from '@/audit/utils';
|
||||
import config from '@/config';
|
||||
import { generateNanoId } from '@db/utils/generators';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
import Container from 'typedi';
|
||||
|
||||
beforeAll(async () => {
|
||||
await testDb.init();
|
||||
|
@ -53,7 +54,7 @@ test('should report webhook lacking authentication', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
await Db.collections.Workflow.save(details);
|
||||
await Container.get(WorkflowRepository).save(details);
|
||||
|
||||
const testAudit = await audit(['instance']);
|
||||
|
||||
|
@ -97,7 +98,7 @@ test('should not report webhooks having basic or header auth', async () => {
|
|||
],
|
||||
};
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
@ -158,7 +159,7 @@ test('should not report webhooks validated by direct children', async () => {
|
|||
},
|
||||
};
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { v4 as uuid } from 'uuid';
|
||||
import { Container } from 'typedi';
|
||||
import * as Db from '@/Db';
|
||||
import { audit } from '@/audit';
|
||||
import { OFFICIAL_RISKY_NODE_TYPES, NODES_REPORT } from '@/audit/constants';
|
||||
import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
import { toReportTitle } from '@/audit/utils';
|
||||
import { mockInstance } from '../shared/utils/';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { CommunityPackagesService } from '@/services/communityPackages.service';
|
||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||
|
||||
import { mockInstance } from '../../shared/mocking';
|
||||
import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
|
||||
const nodesAndCredentials = mockInstance(LoadNodesAndCredentials);
|
||||
nodesAndCredentials.getCustomDirectories.mockReturnValue([]);
|
||||
|
@ -37,7 +38,7 @@ test('should report risky official nodes', async () => {
|
|||
}, {});
|
||||
|
||||
const promises = Object.entries(map).map(async ([nodeType, nodeId]) => {
|
||||
const details = Db.collections.Workflow.create({
|
||||
const details = Container.get(WorkflowRepository).create({
|
||||
name: 'My Test Workflow',
|
||||
active: false,
|
||||
connections: {},
|
||||
|
@ -53,7 +54,7 @@ test('should report risky official nodes', async () => {
|
|||
],
|
||||
});
|
||||
|
||||
return Db.collections.Workflow.save(details);
|
||||
return Container.get(WorkflowRepository).save(details);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue