Skip to content

Commit

Permalink
refactor(core): Continue moving typeorm operators to repositories (…
Browse files Browse the repository at this point in the history
…no-changelog) (n8n-io#8186)

Follow-up to: n8n-io#8163
  • Loading branch information
ivov authored Jan 2, 2024
1 parent 0ca2759 commit 40c1eee
Show file tree
Hide file tree
Showing 35 changed files with 341 additions and 354 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ import {
setWorkflowAsActive,
setWorkflowAsInactive,
updateWorkflow,
getSharedWorkflows,
createWorkflow,
getWorkflowIdsViaTags,
parseTagNames,
getWorkflowsAndCount,
} from './workflows.service';
import { WorkflowService } from '@/workflows/workflow.service';
import { InternalHooks } from '@/InternalHooks';
import { RoleService } from '@/services/role.service';
import { WorkflowHistoryService } from '@/workflows/workflowHistory/workflowHistory.service.ee';
import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflow.repository';
import { TagRepository } from '@/databases/repositories/tag.repository';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';

export = {
createWorkflow: [
Expand Down Expand Up @@ -106,17 +106,24 @@ export = {

if (['owner', 'admin'].includes(req.user.globalRole.name)) {
if (tags) {
const workflowIds = await getWorkflowIdsViaTags(parseTagNames(tags));
const workflowIds = await Container.get(TagRepository).getWorkflowIdsViaTags(
parseTagNames(tags),
);
where.id = In(workflowIds);
}
} else {
const options: { workflowIds?: string[] } = {};

if (tags) {
options.workflowIds = await getWorkflowIdsViaTags(parseTagNames(tags));
options.workflowIds = await Container.get(TagRepository).getWorkflowIdsViaTags(
parseTagNames(tags),
);
}

const sharedWorkflows = await getSharedWorkflows(req.user, options);
const sharedWorkflows = await Container.get(SharedWorkflowRepository).getSharedWorkflows(
req.user,
options,
);

if (!sharedWorkflows.length) {
return res.status(200).json({
Expand All @@ -129,7 +136,7 @@ export = {
where.id = In(workflowsIds);
}

const [workflows, count] = await getWorkflowsAndCount({
const [workflows, count] = await Container.get(WorkflowRepository).findAndCount({
skip: offset,
take: limit,
where,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import type { FindManyOptions, UpdateResult } from 'typeorm';
import { In } from 'typeorm';
import intersection from 'lodash/intersection';

import * as Db from '@/Db';
import type { User } from '@db/entities/User';
import { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
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';
Expand Down Expand Up @@ -39,43 +34,12 @@ export async function getSharedWorkflow(
});
}

export async function getSharedWorkflows(
user: User,
options: {
relations?: string[];
workflowIds?: string[];
},
): Promise<SharedWorkflow[]> {
return Container.get(SharedWorkflowRepository).find({
where: {
...(!['owner', 'admin'].includes(user.globalRole.name) && { userId: user.id }),
...(options.workflowIds && { workflowId: In(options.workflowIds) }),
},
...(options.relations && { relations: options.relations }),
});
}

export async function getWorkflowById(id: string): Promise<WorkflowEntity | null> {
return Container.get(WorkflowRepository).findOne({
where: { id },
});
}

/**
* Returns the workflow IDs that have certain tags.
* Intersection! e.g. workflow needs to have all provided tags.
*/
export async function getWorkflowIdsViaTags(tags: string[]): Promise<string[]> {
const dbTags = await Container.get(TagService).findMany({
where: { name: In(tags) },
relations: ['workflows'],
});

const workflowIdsPerTag = dbTags.map((tag) => tag.workflows.map((workflow) => workflow.id));

return intersection(...workflowIdsPerTag);
}

export async function createWorkflow(
workflow: WorkflowEntity,
user: User,
Expand All @@ -98,14 +62,14 @@ export async function createWorkflow(
});
}

export async function setWorkflowAsActive(workflow: WorkflowEntity): Promise<UpdateResult> {
return Container.get(WorkflowRepository).update(workflow.id, {
export async function setWorkflowAsActive(workflow: WorkflowEntity) {
await Container.get(WorkflowRepository).update(workflow.id, {
active: true,
updatedAt: new Date(),
});
}

export async function setWorkflowAsInactive(workflow: WorkflowEntity): Promise<UpdateResult> {
export async function setWorkflowAsInactive(workflow: WorkflowEntity) {
return Container.get(WorkflowRepository).update(workflow.id, {
active: false,
updatedAt: new Date(),
Expand All @@ -116,16 +80,7 @@ export async function deleteWorkflow(workflow: WorkflowEntity): Promise<Workflow
return Container.get(WorkflowRepository).remove(workflow);
}

export async function getWorkflowsAndCount(
options: FindManyOptions<WorkflowEntity>,
): Promise<[WorkflowEntity[], number]> {
return Container.get(WorkflowRepository).findAndCount(options);
}

export async function updateWorkflow(
workflowId: string,
updateData: WorkflowEntity,
): Promise<UpdateResult> {
export async function updateWorkflow(workflowId: string, updateData: WorkflowEntity) {
return Container.get(WorkflowRepository).update(workflowId, updateData);
}

Expand Down
18 changes: 5 additions & 13 deletions packages/cli/src/UserManagement/PermissionChecker.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type { INode, Workflow } from 'n8n-workflow';
import { NodeOperationError, WorkflowOperationError } from 'n8n-workflow';
import type { FindOptionsWhere } from 'typeorm';
import { In } from 'typeorm';
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';
Expand Down Expand Up @@ -48,17 +45,12 @@ export class PermissionChecker {
workflowUserIds = workflowSharings.map((s) => s.userId);
}

const credentialsWhere: FindOptionsWhere<SharedCredentials> = { userId: In(workflowUserIds) };
const roleId = await Container.get(RoleService).findCredentialOwnerRoleId();

if (!isSharingEnabled()) {
const role = await Container.get(RoleService).findCredentialOwnerRole();
// If credential sharing is not enabled, get only credentials owned by this user
credentialsWhere.roleId = role.id;
}

const credentialSharings = await Container.get(SharedCredentialsRepository).find({
where: credentialsWhere,
});
const credentialSharings = await Container.get(SharedCredentialsRepository).findSharings(
workflowUserIds,
roleId,
);

const accessibleCredIds = credentialSharings.map((s) => s.credentialsId);

Expand Down
7 changes: 6 additions & 1 deletion packages/cli/src/collaboration/collaboration.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { IActiveWorkflowUsersChanged } from '../Interfaces';
import type { OnPushMessageEvent } from '@/push/types';
import { CollaborationState } from '@/collaboration/collaboration.state';
import { TIME } from '@/constants';
import { UserRepository } from '@/databases/repositories/user.repository';

/**
* After how many minutes of inactivity a user should be removed
Expand All @@ -28,6 +29,7 @@ export class CollaborationService {
private readonly push: Push,
private readonly state: CollaborationState,
private readonly userService: UserService,
private readonly userRepository: UserRepository,
) {
if (!push.isBidirectional) {
logger.warn(
Expand Down Expand Up @@ -89,7 +91,10 @@ export class CollaborationService {
if (workflowUserIds.length === 0) {
return;
}
const users = await this.userService.getByIds(this.userService.getManager(), workflowUserIds);
const users = await this.userRepository.getByIds(
this.userService.getManager(),
workflowUserIds,
);

const msgData: IActiveWorkflowUsersChanged = {
workflowId,
Expand Down
11 changes: 3 additions & 8 deletions packages/cli/src/commands/export/credentials.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { flags } from '@oclif/command';
import fs from 'fs';
import path from 'path';
import type { FindOptionsWhere } from 'typeorm';
import { Credentials } from 'n8n-core';
import type { ICredentialsDb, ICredentialsDecryptedDb } from '@/Interfaces';
import { BaseCommand } from '../BaseCommand';
Expand Down Expand Up @@ -107,13 +106,9 @@ export class ExportCredentialsCommand extends BaseCommand {
}
}

const findQuery: FindOptionsWhere<ICredentialsDb> = {};
if (flags.id) {
findQuery.id = flags.id;
}

const credentials: ICredentialsDb[] =
await Container.get(CredentialsRepository).findBy(findQuery);
const credentials: ICredentialsDb[] = await Container.get(CredentialsRepository).findBy(
flags.id ? { id: flags.id } : {},
);

if (flags.decrypted) {
for (let i = 0; i < credentials.length; i++) {
Expand Down
9 changes: 1 addition & 8 deletions packages/cli/src/commands/export/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { flags } from '@oclif/command';
import fs from 'fs';
import path from 'path';
import type { FindOptionsWhere } from 'typeorm';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { BaseCommand } from '../BaseCommand';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
Expand Down Expand Up @@ -101,13 +99,8 @@ export class ExportWorkflowsCommand extends BaseCommand {
}
}

const findQuery: FindOptionsWhere<WorkflowEntity> = {};
if (flags.id) {
findQuery.id = flags.id;
}

const workflows = await Container.get(WorkflowRepository).find({
where: findQuery,
where: flags.id ? { id: flags.id } : {},
relations: ['tags'],
});

Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/commands/ldap/reset.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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';
Expand All @@ -17,7 +16,7 @@ export class Reset extends BaseCommand {
});
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(UserRepository).deleteMany(ldapIdentities.map((i) => i.userId));
await Container.get(SettingsRepository).delete({ key: LDAP_FEATURE_NAME });
await Container.get(SettingsRepository).insert({
key: LDAP_FEATURE_NAME,
Expand Down
13 changes: 6 additions & 7 deletions packages/cli/src/commands/list/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { flags } from '@oclif/command';
import type { FindOptionsWhere } from 'typeorm';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { BaseCommand } from '../BaseCommand';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
Expand Down Expand Up @@ -32,12 +30,13 @@ export class ListWorkflowCommand extends BaseCommand {
this.error('The --active flag has to be passed using true or false');
}

const findQuery: FindOptionsWhere<WorkflowEntity> = {};
if (flags.active !== undefined) {
findQuery.active = flags.active === 'true';
}
const workflowRepository = Container.get(WorkflowRepository);

const workflows =
flags.active !== undefined
? await workflowRepository.findByActiveState(flags.active === 'true')
: await workflowRepository.find();

const workflows = await Container.get(WorkflowRepository).findBy(findQuery);
if (flags.onlyId) {
workflows.forEach((workflow) => this.logger.info(workflow.id));
} else {
Expand Down
12 changes: 3 additions & 9 deletions packages/cli/src/commands/update/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { flags } from '@oclif/command';
import type { FindOptionsWhere } from 'typeorm';
import type { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
import type { WorkflowEntity } from '@db/entities/WorkflowEntity';
import { BaseCommand } from '../BaseCommand';
import { WorkflowRepository } from '@db/repositories/workflow.repository';
import Container from 'typedi';
Expand Down Expand Up @@ -43,7 +40,6 @@ export class UpdateWorkflowCommand extends BaseCommand {
return;
}

const updateQuery: QueryDeepPartialEntity<WorkflowEntity> = {};
if (flags.active === undefined) {
console.info('No update flag like "--active=true" has been set!');
return;
Expand All @@ -54,18 +50,16 @@ export class UpdateWorkflowCommand extends BaseCommand {
return;
}

updateQuery.active = flags.active === 'true';
const newState = flags.active === 'true';

const findQuery: FindOptionsWhere<WorkflowEntity> = {};
if (flags.id) {
this.logger.info(`Deactivating workflow with ID: ${flags.id}`);
findQuery.id = flags.id;
await Container.get(WorkflowRepository).updateActiveState(flags.id, newState);
} else {
this.logger.info('Deactivating all workflows');
findQuery.active = true;
await Container.get(WorkflowRepository).deactivateAll();
}

await Container.get(WorkflowRepository).update(findQuery, updateQuery);
this.logger.info('Done');
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class AuthController {
}

try {
user = await this.userService.findOneOrFail({ where: {} });
user = await this.userRepository.findOneOrFail({ where: {}, relations: ['globalRole'] });
} catch (error) {
throw new InternalServerError(
'No users found in database - did you wipe the users table? Create at least one user.',
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/controllers/invitation.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export class InvitationController {
invitee.lastName = lastName;
invitee.password = await this.passwordUtility.hash(validPassword);

const updatedUser = await this.userService.save(invitee);
const updatedUser = await this.userRepository.save(invitee);

await issueCookie(res, updatedUser);

Expand Down
Loading

0 comments on commit 40c1eee

Please sign in to comment.