mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
refactor: Upgrade typeorm to 0.3.x (#5151)
This commit is contained in:
parent
6608e69457
commit
0a5ab560b1
|
@ -161,7 +161,7 @@
|
|||
"lodash.uniqby": "^4.7.0",
|
||||
"lodash.unset": "^4.5.2",
|
||||
"luxon": "^3.1.0",
|
||||
"mysql2": "~2.3.0",
|
||||
"mysql2": "~2.3.3",
|
||||
"n8n-core": "~0.151.0",
|
||||
"n8n-editor-ui": "~0.177.0",
|
||||
"n8n-nodes-base": "~0.209.0",
|
||||
|
@ -175,7 +175,7 @@
|
|||
"passport": "^0.6.0",
|
||||
"passport-cookie": "^1.0.9",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"pg": "^8.3.0",
|
||||
"pg": "^8.8.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"posthog-node": "^2.2.2",
|
||||
"prom-client": "^13.1.0",
|
||||
|
@ -184,12 +184,12 @@
|
|||
"semver": "^7.3.8",
|
||||
"shelljs": "^0.8.5",
|
||||
"source-map-support": "^0.5.21",
|
||||
"sqlite3": "^5.1.2",
|
||||
"sqlite3": "^5.1.4",
|
||||
"sse-channel": "^4.0.0",
|
||||
"swagger-ui-express": "^4.3.0",
|
||||
"syslog-client": "^1.1.1",
|
||||
"tslib": "1.14.1",
|
||||
"typeorm": "0.2.45",
|
||||
"typeorm": "0.3.11",
|
||||
"uuid": "^8.3.2",
|
||||
"validator": "13.7.0",
|
||||
"winston": "^3.3.3",
|
||||
|
|
|
@ -6,7 +6,6 @@ import bodyParser from 'body-parser';
|
|||
import bodyParserXml from 'body-parser-xml';
|
||||
import compression from 'compression';
|
||||
import parseUrl from 'parseurl';
|
||||
import { getConnectionManager } from 'typeorm';
|
||||
import type { RedisOptions } from 'ioredis';
|
||||
|
||||
import {
|
||||
|
@ -162,10 +161,10 @@ export abstract class AbstractServer {
|
|||
this.app.get('/healthz', async (req, res) => {
|
||||
Logger.debug('Health check started!');
|
||||
|
||||
const connection = getConnectionManager().get();
|
||||
const connection = Db.getConnection();
|
||||
|
||||
try {
|
||||
if (!connection.isConnected) {
|
||||
if (!connection.isInitialized) {
|
||||
// Connection is not active
|
||||
throw new ServiceUnavailableError('No active database connection!');
|
||||
}
|
||||
|
|
|
@ -200,18 +200,18 @@ export class ActiveWorkflowRunner {
|
|||
path = path.slice(0, -1);
|
||||
}
|
||||
|
||||
let webhook = await Db.collections.Webhook.findOne({
|
||||
let webhook = await Db.collections.Webhook.findOneBy({
|
||||
webhookPath: path,
|
||||
method: httpMethod,
|
||||
});
|
||||
let webhookId: string | undefined;
|
||||
|
||||
// check if path is dynamic
|
||||
if (webhook === undefined) {
|
||||
if (webhook === null) {
|
||||
// check if a dynamic webhook path exists
|
||||
const pathElements = path.split('/');
|
||||
webhookId = pathElements.shift();
|
||||
const dynamicWebhooks = await Db.collections.Webhook.find({
|
||||
const dynamicWebhooks = await Db.collections.Webhook.findBy({
|
||||
webhookId,
|
||||
method: httpMethod,
|
||||
pathLength: pathElements.length,
|
||||
|
@ -243,7 +243,7 @@ export class ActiveWorkflowRunner {
|
|||
webhook = dynamicWebhook;
|
||||
}
|
||||
});
|
||||
if (webhook === undefined) {
|
||||
if (webhook === null) {
|
||||
throw new ResponseHelper.NotFoundError(
|
||||
`The requested webhook "${httpMethod} ${path}" is not registered.`,
|
||||
WEBHOOK_PROD_UNREGISTERED_HINT,
|
||||
|
@ -263,10 +263,11 @@ export class ActiveWorkflowRunner {
|
|||
});
|
||||
}
|
||||
|
||||
const workflowData = await Db.collections.Workflow.findOne(webhook.workflowId, {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
where: { id: webhook.workflowId },
|
||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||
});
|
||||
if (workflowData === undefined) {
|
||||
if (workflowData === null) {
|
||||
throw new ResponseHelper.NotFoundError(
|
||||
`Could not find workflow with id "${webhook.workflowId}"`,
|
||||
);
|
||||
|
@ -331,20 +332,19 @@ export class ActiveWorkflowRunner {
|
|||
|
||||
/**
|
||||
* Gets all request methods associated with a single webhook
|
||||
*
|
||||
* @param {string} path webhook path
|
||||
*/
|
||||
async getWebhookMethods(path: string): Promise<string[]> {
|
||||
const webhooks = await Db.collections.Webhook.find({ webhookPath: path });
|
||||
const webhooks = await Db.collections.Webhook.find({
|
||||
select: ['method'],
|
||||
where: { webhookPath: path },
|
||||
});
|
||||
|
||||
// Gather all request methods in string array
|
||||
const webhookMethods: string[] = webhooks.map((webhook) => webhook.method);
|
||||
return webhookMethods;
|
||||
return webhooks.map((webhook) => webhook.method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ids of the currently active workflows
|
||||
*
|
||||
*/
|
||||
async getActiveWorkflows(user?: User): Promise<IWorkflowDb[]> {
|
||||
let activeWorkflows: WorkflowEntity[] = [];
|
||||
|
@ -378,7 +378,10 @@ export class ActiveWorkflowRunner {
|
|||
* @param {string} id The id of the workflow to check
|
||||
*/
|
||||
async isActive(id: string): Promise<boolean> {
|
||||
const workflow = await Db.collections.Workflow.findOne(id);
|
||||
const workflow = await Db.collections.Workflow.findOne({
|
||||
select: ['active'],
|
||||
where: { id },
|
||||
});
|
||||
return !!workflow?.active;
|
||||
}
|
||||
|
||||
|
@ -434,6 +437,7 @@ export class ActiveWorkflowRunner {
|
|||
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
// TODO: this should happen in a transaction, that way we don't need to manually remove this in `catch`
|
||||
await Db.collections.Webhook.insert(webhook);
|
||||
const webhookExists = await workflow.runWebhookMethod(
|
||||
'checkExists',
|
||||
|
@ -503,10 +507,11 @@ export class ActiveWorkflowRunner {
|
|||
*
|
||||
*/
|
||||
async removeWorkflowWebhooks(workflowId: string): Promise<void> {
|
||||
const workflowData = await Db.collections.Workflow.findOne(workflowId, {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
where: { id: workflowId },
|
||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||
});
|
||||
if (workflowData === undefined) {
|
||||
if (workflowData === null) {
|
||||
throw new Error(`Could not find workflow with id "${workflowId}"`);
|
||||
}
|
||||
|
||||
|
@ -772,7 +777,8 @@ export class ActiveWorkflowRunner {
|
|||
let workflowInstance: Workflow;
|
||||
try {
|
||||
if (workflowData === undefined) {
|
||||
workflowData = (await Db.collections.Workflow.findOne(workflowId, {
|
||||
workflowData = (await Db.collections.Workflow.findOne({
|
||||
where: { id: workflowId },
|
||||
relations: ['shared', 'shared.user', 'shared.user.globalRole'],
|
||||
})) as IWorkflowDb;
|
||||
}
|
||||
|
@ -883,7 +889,7 @@ export class ActiveWorkflowRunner {
|
|||
/**
|
||||
* Add a workflow to the activation queue.
|
||||
* Meaning it will keep on trying to activate it in regular
|
||||
* amounts indefinetly.
|
||||
* amounts indefinitely.
|
||||
*/
|
||||
addQueuedWorkflowActivation(
|
||||
activationMode: WorkflowActivateMode,
|
||||
|
@ -962,6 +968,7 @@ export class ActiveWorkflowRunner {
|
|||
*
|
||||
* @param {string} workflowId The id of the workflow to deactivate
|
||||
*/
|
||||
// TODO: this should happen in a transaction
|
||||
async remove(workflowId: string): Promise<void> {
|
||||
if (this.activeWorkflows !== null) {
|
||||
// Remove all the webhooks of the workflow
|
||||
|
|
|
@ -3,10 +3,11 @@ import * as Db from '@/Db';
|
|||
import { InstalledNodes } from '@db/entities/InstalledNodes';
|
||||
import { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||
|
||||
export async function findInstalledPackage(
|
||||
packageName: string,
|
||||
): Promise<InstalledPackages | undefined> {
|
||||
return Db.collections.InstalledPackages.findOne(packageName, { relations: ['installedNodes'] });
|
||||
export async function findInstalledPackage(packageName: string): Promise<InstalledPackages | null> {
|
||||
return Db.collections.InstalledPackages.findOne({
|
||||
where: { packageName },
|
||||
relations: ['installedNodes'],
|
||||
});
|
||||
}
|
||||
|
||||
export async function isPackageInstalled(packageName: string): Promise<boolean> {
|
||||
|
|
|
@ -270,7 +270,7 @@ export class CredentialsHelper extends ICredentialsHelper {
|
|||
relations: ['credentials'],
|
||||
where: { credentials: { id: nodeCredential.id, type }, userId },
|
||||
}).then((shared) => shared.credentials)
|
||||
: await Db.collections.Credentials.findOneOrFail({ id: nodeCredential.id, type });
|
||||
: await Db.collections.Credentials.findOneByOrFail({ id: nodeCredential.id, type });
|
||||
|
||||
if (!credential) {
|
||||
throw new Error(
|
||||
|
@ -765,8 +765,8 @@ export async function getCredentialForUser(
|
|||
*/
|
||||
export async function getCredentialWithoutUser(
|
||||
credentialId: string,
|
||||
): Promise<ICredentialsDb | undefined> {
|
||||
return Db.collections.Credentials.findOne(credentialId);
|
||||
): Promise<ICredentialsDb | null> {
|
||||
return Db.collections.Credentials.findOneBy({ id: credentialId });
|
||||
}
|
||||
|
||||
export function createCredentialsFromCredentialsEntity(
|
||||
|
|
|
@ -4,12 +4,10 @@
|
|||
/* eslint-disable no-case-declarations */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import {
|
||||
Connection,
|
||||
ConnectionOptions,
|
||||
createConnection,
|
||||
DataSource as Connection,
|
||||
DataSourceOptions as ConnectionOptions,
|
||||
EntityManager,
|
||||
EntityTarget,
|
||||
getRepository,
|
||||
LoggerOptions,
|
||||
ObjectLiteral,
|
||||
Repository,
|
||||
|
@ -34,6 +32,8 @@ export const collections = {} as IDatabaseCollections;
|
|||
|
||||
export let connection: Connection;
|
||||
|
||||
export const getConnection = () => connection!;
|
||||
|
||||
export async function transaction<T>(fn: (entityManager: EntityManager) => Promise<T>): Promise<T> {
|
||||
return connection.transaction(fn);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ export async function transaction<T>(fn: (entityManager: EntityManager) => Promi
|
|||
export function linkRepository<Entity extends ObjectLiteral>(
|
||||
entityClass: EntityTarget<Entity>,
|
||||
): Repository<Entity> {
|
||||
return getRepository(entityClass, connection.name);
|
||||
return connection.getRepository(entityClass);
|
||||
}
|
||||
|
||||
export async function getConnectionOptions(dbType: DatabaseType): Promise<ConnectionOptions> {
|
||||
|
@ -124,7 +124,8 @@ export async function init(
|
|||
migrationsTransactionMode: 'each',
|
||||
});
|
||||
|
||||
connection = await createConnection(connectionOptions);
|
||||
connection = new Connection(connectionOptions);
|
||||
await connection.initialize();
|
||||
|
||||
if (!testConnectionOptions && dbType === 'sqlite') {
|
||||
// This specific migration changes database metadata.
|
||||
|
@ -146,8 +147,9 @@ export async function init(
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (migrations.length === 0) {
|
||||
await connection.close();
|
||||
connection = await createConnection(connectionOptions);
|
||||
await connection.destroy();
|
||||
connection = new Connection(connectionOptions);
|
||||
await connection.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ async function createApiRouter(
|
|||
_scopes: unknown,
|
||||
schema: OpenAPIV3.ApiKeySecurityScheme,
|
||||
): Promise<boolean> => {
|
||||
const apiKey = req.headers[schema.name.toLowerCase()];
|
||||
const apiKey = req.headers[schema.name.toLowerCase()] as string;
|
||||
const user = await Db.collections.User.findOne({
|
||||
where: { apiKey },
|
||||
relations: ['globalRole'],
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import type { FindConditions } from 'typeorm';
|
||||
import { UserSettings, Credentials } from 'n8n-core';
|
||||
import { IDataObject, INodeProperties, INodePropertyOptions } from 'n8n-workflow';
|
||||
import * as Db from '@/Db';
|
||||
|
@ -10,17 +9,22 @@ import { ExternalHooks } from '@/ExternalHooks';
|
|||
import { IDependency, IJsonSchema } from '../../../types';
|
||||
import { CredentialRequest } from '@/requests';
|
||||
|
||||
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | undefined> {
|
||||
return Db.collections.Credentials.findOne(credentialId);
|
||||
export async function getCredentials(credentialId: string): Promise<ICredentialsDb | null> {
|
||||
return Db.collections.Credentials.findOneBy({ id: credentialId });
|
||||
}
|
||||
|
||||
export async function getSharedCredentials(
|
||||
userId: string,
|
||||
credentialId: string,
|
||||
relations?: string[],
|
||||
): Promise<SharedCredentials | undefined> {
|
||||
const where: FindConditions<SharedCredentials> = { userId, credentialsId: credentialId };
|
||||
return Db.collections.SharedCredentials.findOne({ where, relations });
|
||||
): Promise<SharedCredentials | null> {
|
||||
return Db.collections.SharedCredentials.findOne({
|
||||
where: {
|
||||
userId,
|
||||
credentialsId: credentialId,
|
||||
},
|
||||
relations,
|
||||
});
|
||||
}
|
||||
|
||||
export async function createCredential(
|
||||
|
@ -53,7 +57,7 @@ export async function saveCredential(
|
|||
user: User,
|
||||
encryptedData: ICredentialsDb,
|
||||
): Promise<CredentialsEntity> {
|
||||
const role = await Db.collections.Role.findOneOrFail({
|
||||
const role = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { parse } from 'flatted';
|
||||
import { In, Not, Raw, LessThan, IsNull, FindOperator } from 'typeorm';
|
||||
import { In, Not, Raw, LessThan, IsNull, FindOptionsWhere } from 'typeorm';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import type { IExecutionFlattedDb, IExecutionResponseApi } from '@/Interfaces';
|
||||
import { ExecutionEntity } from '@db/entities/ExecutionEntity';
|
||||
import { ExecutionStatus } from '@/PublicApi/types';
|
||||
import type { ExecutionStatus } from '@/PublicApi/types';
|
||||
|
||||
function prepareExecutionData(
|
||||
execution: IExecutionFlattedDb | undefined,
|
||||
execution: IExecutionFlattedDb | null,
|
||||
): IExecutionResponseApi | undefined {
|
||||
if (!execution) return undefined;
|
||||
|
||||
|
@ -21,11 +20,10 @@ function prepareExecutionData(
|
|||
}
|
||||
|
||||
function getStatusCondition(status: ExecutionStatus) {
|
||||
const condition: {
|
||||
finished?: boolean;
|
||||
waitTill?: FindOperator<ExecutionEntity>;
|
||||
stoppedAt?: FindOperator<ExecutionEntity>;
|
||||
} = {};
|
||||
const condition: Pick<
|
||||
FindOptionsWhere<IExecutionFlattedDb>,
|
||||
'finished' | 'waitTill' | 'stoppedAt'
|
||||
> = {};
|
||||
|
||||
if (status === 'success') {
|
||||
condition.finished = true;
|
||||
|
@ -65,12 +63,7 @@ export async function getExecutions(params: {
|
|||
status?: ExecutionStatus;
|
||||
excludedExecutionsIds?: string[];
|
||||
}): Promise<IExecutionResponseApi[]> {
|
||||
type WhereClause = Record<
|
||||
string,
|
||||
string | boolean | FindOperator<string | Partial<ExecutionEntity>>
|
||||
>;
|
||||
|
||||
let where: WhereClause = {};
|
||||
let where: FindOptionsWhere<IExecutionFlattedDb> = {};
|
||||
|
||||
if (params.lastId && params.excludedExecutionsIds?.length) {
|
||||
where.id = Raw((id) => `${id} < :lastId AND ${id} NOT IN (:...excludedExecutionsIds)`, {
|
||||
|
|
|
@ -7,7 +7,7 @@ export function isInstanceOwner(user: User): boolean {
|
|||
}
|
||||
|
||||
export async function getWorkflowOwnerRole(): Promise<Role> {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import express from 'express';
|
||||
|
||||
import { FindConditions, FindManyOptions, In } from 'typeorm';
|
||||
import { FindManyOptions, FindOptionsWhere, In } from 'typeorm';
|
||||
|
||||
import * as ActiveWorkflowRunner from '@/ActiveWorkflowRunner';
|
||||
import config from '@/config';
|
||||
|
@ -100,7 +100,7 @@ export = {
|
|||
let workflows: WorkflowEntity[];
|
||||
let count: number;
|
||||
|
||||
const where: FindConditions<WorkflowEntity> = {
|
||||
const where: FindOptionsWhere<WorkflowEntity> = {
|
||||
...(active !== undefined && { active }),
|
||||
};
|
||||
const query: FindManyOptions<WorkflowEntity> = {
|
||||
|
|
|
@ -17,7 +17,7 @@ function insertIf(condition: boolean, elements: string[]): string[] {
|
|||
|
||||
export async function getSharedWorkflowIds(user: User): Promise<string[]> {
|
||||
const sharedWorkflows = await Db.collections.SharedWorkflow.find({
|
||||
where: { user },
|
||||
where: { userId: user.id },
|
||||
});
|
||||
|
||||
return sharedWorkflows.map(({ workflowId }) => workflowId);
|
||||
|
@ -26,10 +26,10 @@ export async function getSharedWorkflowIds(user: User): Promise<string[]> {
|
|||
export async function getSharedWorkflow(
|
||||
user: User,
|
||||
workflowId?: string | undefined,
|
||||
): Promise<SharedWorkflow | undefined> {
|
||||
): Promise<SharedWorkflow | null> {
|
||||
return Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
...(!isInstanceOwner(user) && { user }),
|
||||
...(!isInstanceOwner(user) && { userId: user.id }),
|
||||
...(workflowId && { workflowId }),
|
||||
},
|
||||
relations: [...insertIf(!config.getEnv('workflowTagsDisabled'), ['workflow.tags']), 'workflow'],
|
||||
|
@ -45,14 +45,14 @@ export async function getSharedWorkflows(
|
|||
): Promise<SharedWorkflow[]> {
|
||||
return Db.collections.SharedWorkflow.find({
|
||||
where: {
|
||||
...(!isInstanceOwner(user) && { user }),
|
||||
...(!isInstanceOwner(user) && { userId: user.id }),
|
||||
...(options.workflowIds && { workflowId: In(options.workflowIds) }),
|
||||
},
|
||||
...(options.relations && { relations: options.relations }),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getWorkflowById(id: string): Promise<WorkflowEntity | undefined> {
|
||||
export async function getWorkflowById(id: string): Promise<WorkflowEntity | null> {
|
||||
return Db.collections.Workflow.findOne({
|
||||
where: { id },
|
||||
});
|
||||
|
|
|
@ -1246,9 +1246,9 @@ class Server extends AbstractServer {
|
|||
await queue.stopJob(job);
|
||||
}
|
||||
|
||||
const executionDb = (await Db.collections.Execution.findOne(
|
||||
req.params.id,
|
||||
)) as IExecutionFlattedDb;
|
||||
const executionDb = (await Db.collections.Execution.findOneBy({
|
||||
id: req.params.id,
|
||||
})) as IExecutionFlattedDb;
|
||||
const fullExecutionData = ResponseHelper.unflattenExecutionData(executionDb);
|
||||
|
||||
const returnData: IExecutionsStopData = {
|
||||
|
@ -1452,9 +1452,10 @@ export async function start(): Promise<void> {
|
|||
// Set up event handling
|
||||
initEvents();
|
||||
|
||||
const workflow = await Db.collections.Workflow!.findOne({
|
||||
const workflow = await Db.collections.Workflow.findOne({
|
||||
select: ['createdAt'],
|
||||
order: { createdAt: 'ASC' },
|
||||
where: {},
|
||||
});
|
||||
await InternalHooksManager.getInstance().onServerStarted(diagnosticInfo, workflow?.createdAt);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { EntityManager, getConnection } from 'typeorm';
|
||||
import type { EntityManager } from 'typeorm';
|
||||
|
||||
import { getConnection } from '@/Db';
|
||||
import { TagEntity } from '@db/entities/TagEntity';
|
||||
|
||||
import { ITagToImport, ITagWithCountDb, IWorkflowToImport } from '@/Interfaces';
|
||||
import type { ITagToImport, ITagWithCountDb, IWorkflowToImport } from '@/Interfaces';
|
||||
|
||||
// ----------------------------------
|
||||
// utils
|
||||
|
|
|
@ -5,11 +5,11 @@ import {
|
|||
Workflow,
|
||||
WorkflowOperationError,
|
||||
} from 'n8n-workflow';
|
||||
import { FindConditions, In } from 'typeorm';
|
||||
import { FindOptionsWhere, In } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import config from '@/config';
|
||||
import type { SharedCredentials } from '@db/entities/SharedCredentials';
|
||||
import { getRole, getWorkflowOwner, isSharingEnabled } from './UserManagementHelper';
|
||||
import { getRoleId, getWorkflowOwner, isSharingEnabled } from './UserManagementHelper';
|
||||
import { WorkflowsService } from '@/workflows/workflows.services';
|
||||
import { UserService } from '@/user/user.service';
|
||||
|
||||
|
@ -28,7 +28,8 @@ export class PermissionChecker {
|
|||
|
||||
// allow if requesting user is instance owner
|
||||
|
||||
const user = await Db.collections.User.findOneOrFail(userId, {
|
||||
const user = await Db.collections.User.findOneOrFail({
|
||||
where: { id: userId },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
||||
|
@ -47,11 +48,11 @@ export class PermissionChecker {
|
|||
workflowUserIds = workflowSharings.map((s) => s.userId);
|
||||
}
|
||||
|
||||
const credentialsWhere: FindConditions<SharedCredentials> = { userId: In(workflowUserIds) };
|
||||
const credentialsWhere: FindOptionsWhere<SharedCredentials> = { userId: In(workflowUserIds) };
|
||||
|
||||
if (!isSharingEnabled()) {
|
||||
// If credential sharing is not enabled, get only credentials owned by this user
|
||||
credentialsWhere.role = await getRole('credential', 'owner');
|
||||
credentialsWhere.roleId = await getRoleId('credential', 'owner');
|
||||
}
|
||||
|
||||
const credentialSharings = await Db.collections.SharedCredentials.find({
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { INode, NodeOperationError, Workflow } from 'n8n-workflow';
|
||||
import { In } from 'typeorm';
|
||||
import express from 'express';
|
||||
import { compare, genSaltSync, hash } from 'bcryptjs';
|
||||
|
@ -21,7 +20,7 @@ export async function getWorkflowOwner(workflowId: string): Promise<User> {
|
|||
const workflowOwnerRole = await RoleService.get({ name: 'owner', scope: 'workflow' });
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneOrFail({
|
||||
where: { workflowId, role: workflowOwnerRole },
|
||||
where: { workflowId, roleId: workflowOwnerRole?.id ?? undefined },
|
||||
relations: ['user', 'user.globalRole'],
|
||||
});
|
||||
|
||||
|
@ -59,35 +58,26 @@ export function isUserManagementDisabled(): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
async function getInstanceOwnerRole(): Promise<Role> {
|
||||
const ownerRole = await Db.collections.Role.findOneOrFail({
|
||||
where: {
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
},
|
||||
});
|
||||
return ownerRole;
|
||||
}
|
||||
|
||||
export async function getInstanceOwner(): Promise<User> {
|
||||
const ownerRole = await getInstanceOwnerRole();
|
||||
|
||||
const owner = await Db.collections.User.findOneOrFail({
|
||||
relations: ['globalRole'],
|
||||
where: {
|
||||
globalRole: ownerRole,
|
||||
},
|
||||
});
|
||||
return owner;
|
||||
}
|
||||
|
||||
export async function getRole(scope: Role['scope'], name: Role['name']): Promise<Role> {
|
||||
export async function getRoleId(scope: Role['scope'], name: Role['name']): Promise<Role['id']> {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
select: ['id'],
|
||||
where: {
|
||||
name,
|
||||
scope,
|
||||
},
|
||||
}).then((role) => role.id);
|
||||
}
|
||||
|
||||
export async function getInstanceOwner(): Promise<User> {
|
||||
const ownerRoleId = await getRoleId('global', 'owner');
|
||||
|
||||
const owner = await Db.collections.User.findOneOrFail({
|
||||
relations: ['globalRole'],
|
||||
where: {
|
||||
globalRoleId: ownerRoleId,
|
||||
},
|
||||
});
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,7 +158,8 @@ export function addInviteLinktoUser(user: PublicUser, inviterId: string): Public
|
|||
}
|
||||
|
||||
export async function getUserById(userId: string): Promise<User> {
|
||||
const user = await Db.collections.User.findOneOrFail(userId, {
|
||||
const user = await Db.collections.User.findOneOrFail({
|
||||
where: { id: userId },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
return user;
|
||||
|
|
|
@ -36,7 +36,8 @@ export function issueJWT(user: User): JwtToken {
|
|||
}
|
||||
|
||||
export async function resolveJwtContent(jwtPayload: JwtPayload): Promise<User> {
|
||||
const user = await Db.collections.User.findOne(jwtPayload.id, {
|
||||
const user = await Db.collections.User.findOne({
|
||||
where: { id: jwtPayload.id },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
|
||||
|
|
|
@ -30,14 +30,12 @@ export function authenticationMethods(this: N8nApp): void {
|
|||
throw new Error('Password is required to log in');
|
||||
}
|
||||
|
||||
let user: User | undefined;
|
||||
let user: User | null;
|
||||
try {
|
||||
user = await Db.collections.User.findOne(
|
||||
{ email },
|
||||
{
|
||||
relations: ['globalRole'],
|
||||
},
|
||||
);
|
||||
user = await Db.collections.User.findOne({
|
||||
where: { email },
|
||||
relations: ['globalRole'],
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error('Unable to access database.');
|
||||
}
|
||||
|
@ -77,7 +75,7 @@ export function authenticationMethods(this: N8nApp): void {
|
|||
}
|
||||
|
||||
try {
|
||||
user = await Db.collections.User.findOneOrFail({ relations: ['globalRole'] });
|
||||
user = await Db.collections.User.findOneOrFail({ relations: ['globalRole'], where: {} });
|
||||
} catch (error) {
|
||||
throw new ResponseHelper.InternalServerError(
|
||||
'No users found in database - did you wipe the users table? Create at least one user.',
|
||||
|
|
|
@ -54,12 +54,10 @@ export function addRoutes(this: N8nApp, ignoredEndpoints: string[], restEndpoint
|
|||
|
||||
// skip authentication if user management is disabled
|
||||
if (isUserManagementDisabled()) {
|
||||
req.user = await Db.collections.User.findOneOrFail(
|
||||
{},
|
||||
{
|
||||
relations: ['globalRole'],
|
||||
},
|
||||
);
|
||||
req.user = await Db.collections.User.findOneOrFail({
|
||||
relations: ['globalRole'],
|
||||
where: {},
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,9 @@ export function ownerNamespace(this: N8nApp): void {
|
|||
throw new ResponseHelper.BadRequestError('First and last names are mandatory');
|
||||
}
|
||||
|
||||
let owner = await Db.collections.User.findOne(userId, {
|
||||
let owner = await Db.collections.User.findOne({
|
||||
relations: ['globalRole'],
|
||||
where: { id: userId },
|
||||
});
|
||||
|
||||
if (!owner || (owner.globalRole.scope === 'global' && owner.globalRole.name !== 'owner')) {
|
||||
|
|
|
@ -52,7 +52,7 @@ export function passwordResetNamespace(this: N8nApp): void {
|
|||
}
|
||||
|
||||
// User should just be able to reset password if one is already present
|
||||
const user = await Db.collections.User.findOne({ email, password: Not(IsNull()) });
|
||||
const user = await Db.collections.User.findOneBy({ email, password: Not(IsNull()) });
|
||||
|
||||
if (!user?.password) {
|
||||
Logger.debug(
|
||||
|
@ -133,7 +133,7 @@ export function passwordResetNamespace(this: N8nApp): void {
|
|||
// Timestamp is saved in seconds
|
||||
const currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Db.collections.User.findOneBy({
|
||||
id,
|
||||
resetPasswordToken,
|
||||
resetPasswordTokenExpiration: MoreThanOrEqual(currentTimestamp),
|
||||
|
@ -184,7 +184,7 @@ export function passwordResetNamespace(this: N8nApp): void {
|
|||
// Timestamp is saved in seconds
|
||||
const currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
|
||||
const user = await Db.collections.User.findOne({
|
||||
const user = await Db.collections.User.findOneBy({
|
||||
id: userId,
|
||||
resetPasswordToken,
|
||||
resetPasswordTokenExpiration: MoreThanOrEqual(currentTimestamp),
|
||||
|
|
|
@ -85,7 +85,7 @@ export function usersNamespace(this: N8nApp): void {
|
|||
createUsers[invite.email.toLowerCase()] = null;
|
||||
});
|
||||
|
||||
const role = await Db.collections.Role.findOne({ scope: 'global', name: 'member' });
|
||||
const role = await Db.collections.Role.findOneBy({ scope: 'global', name: 'member' });
|
||||
|
||||
if (!role) {
|
||||
Logger.error(
|
||||
|
@ -434,7 +434,7 @@ export function usersNamespace(this: N8nApp): void {
|
|||
.getRepository(SharedWorkflow)
|
||||
.find({
|
||||
select: ['workflowId'],
|
||||
where: { userId: userToDelete.id, role: workflowOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: workflowOwnerRole?.id },
|
||||
})
|
||||
.then((sharedWorkflows) => sharedWorkflows.map(({ workflowId }) => workflowId));
|
||||
|
||||
|
@ -459,7 +459,7 @@ export function usersNamespace(this: N8nApp): void {
|
|||
.getRepository(SharedCredentials)
|
||||
.find({
|
||||
select: ['credentialsId'],
|
||||
where: { user: userToDelete, role: credentialOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: credentialOwnerRole?.id },
|
||||
})
|
||||
.then((sharedCredentials) =>
|
||||
sharedCredentials.map(({ credentialsId }) => credentialsId),
|
||||
|
@ -495,11 +495,11 @@ export function usersNamespace(this: N8nApp): void {
|
|||
const [ownedSharedWorkflows, ownedSharedCredentials] = await Promise.all([
|
||||
Db.collections.SharedWorkflow.find({
|
||||
relations: ['workflow'],
|
||||
where: { user: userToDelete, role: workflowOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: workflowOwnerRole?.id },
|
||||
}),
|
||||
Db.collections.SharedCredentials.find({
|
||||
relations: ['credentials'],
|
||||
where: { user: userToDelete, role: credentialOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: credentialOwnerRole?.id },
|
||||
}),
|
||||
]);
|
||||
|
||||
|
@ -546,7 +546,7 @@ export function usersNamespace(this: N8nApp): void {
|
|||
);
|
||||
}
|
||||
|
||||
const reinvitee = await Db.collections.User.findOne({ id: idToReinvite });
|
||||
const reinvitee = await Db.collections.User.findOneBy({ id: idToReinvite });
|
||||
|
||||
if (!reinvitee) {
|
||||
Logger.debug(
|
||||
|
|
|
@ -107,9 +107,9 @@ export class WaitTrackerClass {
|
|||
}
|
||||
|
||||
// Also check in database
|
||||
const execution = await Db.collections.Execution.findOne(executionId);
|
||||
const execution = await Db.collections.Execution.findOneBy({ id: executionId });
|
||||
|
||||
if (execution === undefined || !execution.waitTill) {
|
||||
if (execution === null || !execution.waitTill) {
|
||||
throw new Error(`The execution ID "${executionId}" could not be found.`);
|
||||
}
|
||||
|
||||
|
@ -146,9 +146,11 @@ export class WaitTrackerClass {
|
|||
|
||||
(async () => {
|
||||
// Get the data to execute
|
||||
const fullExecutionDataFlatted = await Db.collections.Execution.findOne(executionId);
|
||||
const fullExecutionDataFlatted = await Db.collections.Execution.findOneBy({
|
||||
id: executionId,
|
||||
});
|
||||
|
||||
if (fullExecutionDataFlatted === undefined) {
|
||||
if (fullExecutionDataFlatted === null) {
|
||||
throw new Error(`The execution with the id "${executionId}" does not exist.`);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ export class WaitingWebhooks {
|
|||
const executionId = pathParts.shift();
|
||||
const path = pathParts.join('/');
|
||||
|
||||
const execution = await Db.collections.Execution.findOne(executionId);
|
||||
const execution = await Db.collections.Execution.findOneBy({ id: executionId });
|
||||
|
||||
if (execution === undefined) {
|
||||
if (execution === null) {
|
||||
throw new ResponseHelper.NotFoundError(`The execution "${executionId} does not exist.`);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ export async function WorkflowCredentials(nodes: INode[]): Promise<IWorkflowCred
|
|||
|
||||
if (!returnCredentials[type][nodeCredentials.id]) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
foundCredentials = await Db.collections.Credentials.findOne({
|
||||
foundCredentials = await Db.collections.Credentials.findOneBy({
|
||||
id: nodeCredentials.id,
|
||||
type,
|
||||
});
|
||||
|
|
|
@ -402,9 +402,9 @@ export function hookFunctionsPreExecute(parentProcessMode?: string): IWorkflowEx
|
|||
{ executionId: this.executionId, nodeName },
|
||||
);
|
||||
|
||||
const execution = await Db.collections.Execution.findOne(this.executionId);
|
||||
const execution = await Db.collections.Execution.findOneBy({ id: this.executionId });
|
||||
|
||||
if (execution === undefined) {
|
||||
if (execution === null) {
|
||||
// Something went badly wrong if this happens.
|
||||
// This check is here mostly to make typescript happy.
|
||||
return;
|
||||
|
@ -829,7 +829,7 @@ export async function getWorkflowData(
|
|||
);
|
||||
}
|
||||
|
||||
let workflowData: IWorkflowBase | undefined;
|
||||
let workflowData: IWorkflowBase | null;
|
||||
if (workflowInfo.id !== undefined) {
|
||||
if (!Db.isInitialized) {
|
||||
// The first time executeWorkflow gets called the Database has
|
||||
|
@ -845,7 +845,7 @@ export async function getWorkflowData(
|
|||
throw new Error(`The workflow with the id "${workflowInfo.id}" does not exist.`);
|
||||
}
|
||||
} else {
|
||||
workflowData = workflowInfo.code;
|
||||
workflowData = workflowInfo.code ?? null;
|
||||
if (workflowData) {
|
||||
if (!workflowData.id) {
|
||||
workflowData.id = parentWorkflowId;
|
||||
|
|
|
@ -88,7 +88,7 @@ export async function executeErrorWorkflow(
|
|||
): Promise<void> {
|
||||
// Wrap everything in try/catch to make sure that no errors bubble up and all get caught here
|
||||
try {
|
||||
let workflowData;
|
||||
let workflowData: WorkflowEntity | null = null;
|
||||
if (workflowId !== workflowErrorData.workflow.id) {
|
||||
// To make this code easier to understand, we split it in 2 parts:
|
||||
// 1) Fetch the owner of the errored workflows and then
|
||||
|
@ -99,7 +99,7 @@ export async function executeErrorWorkflow(
|
|||
const user = await getWorkflowOwner(workflowErrorData.workflow.id!);
|
||||
|
||||
if (user.globalRole.name === 'owner') {
|
||||
workflowData = await Db.collections.Workflow.findOne({ id: workflowId });
|
||||
workflowData = await Db.collections.Workflow.findOneBy({ id: workflowId });
|
||||
} else {
|
||||
const sharedWorkflowData = await Db.collections.SharedWorkflow.findOne({
|
||||
where: { workflowId, userId: user.id },
|
||||
|
@ -110,10 +110,10 @@ export async function executeErrorWorkflow(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
workflowData = await Db.collections.Workflow.findOne({ id: workflowId });
|
||||
workflowData = await Db.collections.Workflow.findOneBy({ id: workflowId });
|
||||
}
|
||||
|
||||
if (workflowData === undefined) {
|
||||
if (workflowData === null) {
|
||||
// The error workflow could not be found
|
||||
Logger.error(
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
|
@ -254,21 +254,13 @@ export async function saveStaticDataById(
|
|||
|
||||
/**
|
||||
* Returns the static data of workflow
|
||||
*
|
||||
* @param {(string)} workflowId The id of the workflow to get static data of
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export async function getStaticDataById(workflowId: string) {
|
||||
const workflowData = await Db.collections.Workflow.findOne(workflowId, {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
select: ['staticData'],
|
||||
where: { id: workflowId },
|
||||
});
|
||||
|
||||
if (workflowData === undefined) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
return workflowData.staticData || {};
|
||||
return workflowData?.staticData ?? {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -312,7 +304,7 @@ export async function replaceInvalidCredentials(workflow: WorkflowEntity): Promi
|
|||
credentialsByName[nodeCredentialType] = {};
|
||||
}
|
||||
if (credentialsByName[nodeCredentialType][name] === undefined) {
|
||||
const credentials = await Db.collections.Credentials.find({
|
||||
const credentials = await Db.collections.Credentials.findBy({
|
||||
name,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -348,7 +340,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.findOne({
|
||||
const credentials = await Db.collections.Credentials.findOneBy({
|
||||
id: nodeCredentials.id,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -362,7 +354,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.find({
|
||||
const credsByName = await Db.collections.Credentials.findBy({
|
||||
name: nodeCredentials.name,
|
||||
type: nodeCredentialType,
|
||||
});
|
||||
|
@ -414,14 +406,17 @@ export async function isBelowOnboardingThreshold(user: User): Promise<boolean> {
|
|||
let belowThreshold = true;
|
||||
const skippedTypes = ['n8n-nodes-base.start', 'n8n-nodes-base.stickyNote'];
|
||||
|
||||
const workflowOwnerRole = await Db.collections.Role.findOne({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
const workflowOwnerRoleId = await Db.collections.Role.findOne({
|
||||
select: ['id'],
|
||||
where: {
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
},
|
||||
}).then((role) => role?.id);
|
||||
const ownedWorkflowsIds = await Db.collections.SharedWorkflow.find({
|
||||
where: {
|
||||
user,
|
||||
role: workflowOwnerRole,
|
||||
userId: user.id,
|
||||
roleId: workflowOwnerRoleId,
|
||||
},
|
||||
select: ['workflowId'],
|
||||
}).then((ownedWorkflows) => ownedWorkflows.map(({ workflowId }) => workflowId));
|
||||
|
|
|
@ -527,9 +527,9 @@ export class WorkflowRunner {
|
|||
reject(error);
|
||||
}
|
||||
|
||||
const executionDb = (await Db.collections.Execution.findOne(
|
||||
executionId,
|
||||
)) as IExecutionFlattedDb;
|
||||
const executionDb = (await Db.collections.Execution.findOneBy({
|
||||
id: executionId,
|
||||
})) as IExecutionFlattedDb;
|
||||
const fullExecutionData = ResponseHelper.unflattenExecutionData(executionDb);
|
||||
const runData = {
|
||||
data: fullExecutionData.data,
|
||||
|
|
|
@ -99,11 +99,14 @@ e2eController.post('/db/setup-owner', bodyParser.json(), async (req, res) => {
|
|||
}
|
||||
|
||||
const globalRole = await Db.collections.Role.findOneOrFail({
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
select: ['id'],
|
||||
where: {
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
},
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOneOrFail({ globalRole });
|
||||
const owner = await Db.collections.User.findOneByOrFail({ globalRoleId: globalRole.id });
|
||||
|
||||
await Db.collections.User.update(owner.id, {
|
||||
email: req.body.email,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MoreThanOrEqual } from 'typeorm';
|
||||
import { FindOperator, MoreThanOrEqual } from 'typeorm';
|
||||
import { DateUtils } from 'typeorm/util/DateUtils';
|
||||
import * as Db from '@/Db';
|
||||
import config from '@/config';
|
||||
|
@ -46,7 +46,7 @@ async function getExecutionsInPastDays(days: number) {
|
|||
return Db.collections.Execution.find({
|
||||
select: ['workflowData'],
|
||||
where: {
|
||||
startedAt: MoreThanOrEqual(utcDate),
|
||||
startedAt: MoreThanOrEqual(utcDate) as unknown as FindOperator<Date>,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ export abstract class BaseCommand extends Command {
|
|||
};
|
||||
|
||||
async getInstanceOwner(): Promise<User> {
|
||||
const globalRole = await Db.collections.Role.findOneOrFail({
|
||||
const globalRole = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOne({ globalRole });
|
||||
const owner = await Db.collections.User.findOneBy({ globalRoleId: globalRole.id });
|
||||
|
||||
if (owner) return owner;
|
||||
|
||||
|
@ -53,6 +53,6 @@ export abstract class BaseCommand extends Command {
|
|||
|
||||
await Db.collections.User.save(user);
|
||||
|
||||
return Db.collections.User.findOneOrFail({ globalRole });
|
||||
return Db.collections.User.findOneByOrFail({ globalRoleId: globalRole.id });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable no-console */
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { Connection, ConnectionOptions, createConnection } from 'typeorm';
|
||||
import { DataSource as Connection, DataSourceOptions as ConnectionOptions } from 'typeorm';
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
|
||||
import { getLogger } from '@/Logger';
|
||||
|
@ -34,11 +34,12 @@ export class DbRevertMigrationCommand extends Command {
|
|||
dropSchema: false,
|
||||
logging: ['query', 'error', 'schema'],
|
||||
};
|
||||
connection = await createConnection(connectionOptions);
|
||||
connection = new Connection(connectionOptions);
|
||||
await connection.initialize();
|
||||
await connection.undoLastMigration();
|
||||
await connection.close();
|
||||
await connection.destroy();
|
||||
} catch (error) {
|
||||
if (connection) await connection.close();
|
||||
if (connection?.isInitialized) await connection.destroy();
|
||||
|
||||
console.error('Error reverting last migration. See log messages for details.');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
|
|
|
@ -72,7 +72,7 @@ export class Execute extends Command {
|
|||
}
|
||||
|
||||
let workflowId: string | undefined;
|
||||
let workflowData: IWorkflowBase | undefined;
|
||||
let workflowData: IWorkflowBase | null = null;
|
||||
if (flags.file) {
|
||||
// Path to workflow is given
|
||||
try {
|
||||
|
@ -91,7 +91,7 @@ export class Execute extends Command {
|
|||
// Do a basic check if the data in the file looks right
|
||||
// TODO: Later check with the help of TypeScript data if it is valid or not
|
||||
if (
|
||||
workflowData === undefined ||
|
||||
workflowData === null ||
|
||||
workflowData.nodes === undefined ||
|
||||
workflowData.connections === undefined
|
||||
) {
|
||||
|
@ -108,8 +108,8 @@ export class Execute extends Command {
|
|||
if (flags.id) {
|
||||
// Id of workflow is given
|
||||
workflowId = flags.id;
|
||||
workflowData = await Db.collections.Workflow.findOne(workflowId);
|
||||
if (workflowData === undefined) {
|
||||
workflowData = await Db.collections.Workflow.findOneBy({ id: workflowId });
|
||||
if (workflowData === null) {
|
||||
console.info(`The workflow with the id "${workflowId}" does not exist.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { LoggerProxy } from 'n8n-workflow';
|
|||
|
||||
import fs from 'fs';
|
||||
import glob from 'fast-glob';
|
||||
import { EntityManager, getConnection } from 'typeorm';
|
||||
import type { EntityManager } from 'typeorm';
|
||||
import { getLogger } from '@/Logger';
|
||||
import * as Db from '@/Db';
|
||||
import { User } from '@db/entities/User';
|
||||
|
@ -100,7 +100,7 @@ export class ImportCredentialsCommand extends Command {
|
|||
|
||||
totalImported = files.length;
|
||||
|
||||
await getConnection().transaction(async (transactionManager) => {
|
||||
await Db.getConnection().transaction(async (transactionManager) => {
|
||||
this.transactionManager = transactionManager;
|
||||
for (const file of files) {
|
||||
const credential = JSON.parse(fs.readFileSync(file, { encoding: 'utf8' }));
|
||||
|
@ -128,7 +128,7 @@ export class ImportCredentialsCommand extends Command {
|
|||
);
|
||||
}
|
||||
|
||||
await getConnection().transaction(async (transactionManager) => {
|
||||
await Db.getConnection().transaction(async (transactionManager) => {
|
||||
this.transactionManager = transactionManager;
|
||||
for (const credential of credentials) {
|
||||
if (typeof credential.data === 'object') {
|
||||
|
@ -187,7 +187,9 @@ export class ImportCredentialsCommand extends Command {
|
|||
where: { name: 'owner', scope: 'global' },
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOne({ globalRole: ownerGlobalRole });
|
||||
const owner =
|
||||
ownerGlobalRole &&
|
||||
(await Db.collections.User.findOneBy({ globalRoleId: ownerGlobalRole.id }));
|
||||
|
||||
if (!owner) {
|
||||
throw new Error(`Failed to find owner. ${FIX_INSTRUCTION}`);
|
||||
|
@ -197,7 +199,7 @@ export class ImportCredentialsCommand extends Command {
|
|||
}
|
||||
|
||||
private async getAssignee(userId: string) {
|
||||
const user = await Db.collections.User.findOne(userId);
|
||||
const user = await Db.collections.User.findOneBy({ id: userId });
|
||||
|
||||
if (!user) {
|
||||
throw new Error(`Failed to find user with ID ${userId}`);
|
||||
|
|
|
@ -16,7 +16,7 @@ import { INode, INodeCredentialsDetails, LoggerProxy } from 'n8n-workflow';
|
|||
import fs from 'fs';
|
||||
import glob from 'fast-glob';
|
||||
import { UserSettings } from 'n8n-core';
|
||||
import { EntityManager, getConnection } from 'typeorm';
|
||||
import type { EntityManager } from 'typeorm';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { getLogger } from '@/Logger';
|
||||
import * as Db from '@/Db';
|
||||
|
@ -123,7 +123,7 @@ export class ImportWorkflowsCommand extends Command {
|
|||
|
||||
totalImported = files.length;
|
||||
|
||||
await getConnection().transaction(async (transactionManager) => {
|
||||
await Db.getConnection().transaction(async (transactionManager) => {
|
||||
this.transactionManager = transactionManager;
|
||||
|
||||
for (const file of files) {
|
||||
|
@ -158,7 +158,7 @@ export class ImportWorkflowsCommand extends Command {
|
|||
|
||||
totalImported = workflows.length;
|
||||
|
||||
await getConnection().transaction(async (transactionManager) => {
|
||||
await Db.getConnection().transaction(async (transactionManager) => {
|
||||
this.transactionManager = transactionManager;
|
||||
|
||||
for (const workflow of workflows) {
|
||||
|
@ -229,7 +229,9 @@ export class ImportWorkflowsCommand extends Command {
|
|||
where: { name: 'owner', scope: 'global' },
|
||||
});
|
||||
|
||||
const owner = await Db.collections.User.findOne({ globalRole: ownerGlobalRole });
|
||||
const owner =
|
||||
ownerGlobalRole &&
|
||||
(await Db.collections.User.findOneBy({ globalRoleId: ownerGlobalRole?.id }));
|
||||
|
||||
if (!owner) {
|
||||
throw new Error(`Failed to find owner. ${FIX_INSTRUCTION}`);
|
||||
|
@ -239,7 +241,7 @@ export class ImportWorkflowsCommand extends Command {
|
|||
}
|
||||
|
||||
private async getAssignee(userId: string) {
|
||||
const user = await Db.collections.User.findOne(userId);
|
||||
const user = await Db.collections.User.findOneBy({ id: userId });
|
||||
|
||||
if (!user) {
|
||||
throw new Error(`Failed to find user with ID ${userId}`);
|
||||
|
|
|
@ -304,7 +304,7 @@ export class Start extends Command {
|
|||
await UserSettings.getEncryptionKey();
|
||||
|
||||
// Load settings from database and set them to config.
|
||||
const databaseSettings = await Db.collections.Settings.find({ loadOnStartup: true });
|
||||
const databaseSettings = await Db.collections.Settings.findBy({ loadOnStartup: true });
|
||||
databaseSettings.forEach((setting) => {
|
||||
config.set(setting.key, JSON.parse(setting.value));
|
||||
});
|
||||
|
|
|
@ -9,23 +9,23 @@ export class Reset extends BaseCommand {
|
|||
async run(): Promise<void> {
|
||||
const owner = await this.getInstanceOwner();
|
||||
|
||||
const ownerWorkflowRole = await Db.collections.Role.findOneOrFail({
|
||||
const ownerWorkflowRole = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
||||
const ownerCredentialRole = await Db.collections.Role.findOneOrFail({
|
||||
const ownerCredentialRole = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
||||
await Db.collections.SharedWorkflow.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerWorkflowRole },
|
||||
{ userId: Not(owner.id), roleId: ownerWorkflowRole.id },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
await Db.collections.SharedCredentials.update(
|
||||
{ user: { id: Not(owner.id) }, role: ownerCredentialRole },
|
||||
{ userId: Not(owner.id), roleId: ownerCredentialRole.id },
|
||||
{ user: owner },
|
||||
);
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ import {
|
|||
sleep,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { FindOneOptions, getConnectionManager } from 'typeorm';
|
||||
|
||||
import { CredentialsOverwrites } from '@/CredentialsOverwrites';
|
||||
import { CredentialTypes } from '@/CredentialTypes';
|
||||
import * as Db from '@/Db';
|
||||
|
@ -125,7 +123,7 @@ export class Worker extends Command {
|
|||
|
||||
async runJob(job: Queue.Job, nodeTypes: INodeTypes): Promise<Queue.JobResponse> {
|
||||
const { executionId, loadStaticData } = job.data;
|
||||
const executionDb = await Db.collections.Execution.findOne(executionId);
|
||||
const executionDb = await Db.collections.Execution.findOneBy({ id: executionId });
|
||||
|
||||
if (!executionDb) {
|
||||
LoggerProxy.error(
|
||||
|
@ -145,14 +143,13 @@ export class Worker extends Command {
|
|||
|
||||
let { staticData } = currentExecutionDb.workflowData;
|
||||
if (loadStaticData) {
|
||||
const findOptions = {
|
||||
const workflowData = await Db.collections.Workflow.findOne({
|
||||
select: ['id', 'staticData'],
|
||||
} as FindOneOptions;
|
||||
const workflowData = await Db.collections.Workflow.findOne(
|
||||
currentExecutionDb.workflowData.id,
|
||||
findOptions,
|
||||
);
|
||||
if (workflowData === undefined) {
|
||||
where: {
|
||||
id: currentExecutionDb.workflowData.id,
|
||||
},
|
||||
});
|
||||
if (workflowData === null) {
|
||||
LoggerProxy.error(
|
||||
'Worker execution failed because workflow could not be found in database.',
|
||||
{
|
||||
|
@ -384,10 +381,10 @@ export class Worker extends Command {
|
|||
async (req: express.Request, res: express.Response) => {
|
||||
LoggerProxy.debug('Health check started!');
|
||||
|
||||
const connection = getConnectionManager().get();
|
||||
const connection = Db.getConnection();
|
||||
|
||||
try {
|
||||
if (!connection.isConnected) {
|
||||
if (!connection.isInitialized) {
|
||||
// Connection is not active
|
||||
throw new Error('No active database connection!');
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ credentialsController.patch(
|
|||
|
||||
const responseData = await CredentialsService.update(credentialId, newCredentialData);
|
||||
|
||||
if (responseData === undefined) {
|
||||
if (responseData === null) {
|
||||
throw new ResponseHelper.NotFoundError(
|
||||
`Credential ID "${credentialId}" could not be found to be updated.`,
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
import { DeleteResult, EntityManager, FindConditions, In, Not } from 'typeorm';
|
||||
import { DeleteResult, EntityManager, FindOptionsWhere, In, Not } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import { RoleService } from '@/role/role.service';
|
||||
import { CredentialsEntity } from '@db/entities/CredentialsEntity';
|
||||
|
@ -33,14 +33,14 @@ export class EECredentialsService extends CredentialsService {
|
|||
credentialId: string,
|
||||
relations: string[] = ['credentials'],
|
||||
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
||||
): Promise<SharedCredentials | undefined> {
|
||||
const where: FindConditions<SharedCredentials> = { credentialsId: credentialId };
|
||||
): Promise<SharedCredentials | null> {
|
||||
const where: FindOptionsWhere<SharedCredentials> = { credentialsId: credentialId };
|
||||
|
||||
// Omit user from where if the requesting user is the global
|
||||
// owner. This allows the global owner to view and delete
|
||||
// credentials they don't own.
|
||||
if (!allowGlobalOwner || user.globalRole.name !== 'owner') {
|
||||
where.user = { id: user.id };
|
||||
where.userId = user.id;
|
||||
}
|
||||
|
||||
return Db.collections.SharedCredentials.findOne({
|
||||
|
@ -65,7 +65,7 @@ export class EECredentialsService extends CredentialsService {
|
|||
credentialId: string,
|
||||
userIds: string[],
|
||||
): Promise<DeleteResult> {
|
||||
const conditions: FindConditions<SharedCredentials> = {
|
||||
const conditions: FindOptionsWhere<SharedCredentials> = {
|
||||
credentialsId: credentialId,
|
||||
userId: Not(In(userIds)),
|
||||
};
|
||||
|
@ -86,9 +86,9 @@ export class EECredentialsService extends CredentialsService {
|
|||
.filter((user) => !user.isPending)
|
||||
.map((user) =>
|
||||
Db.collections.SharedCredentials.create({
|
||||
credentials: credential,
|
||||
user,
|
||||
role,
|
||||
credentialsId: credential.id,
|
||||
userId: user.id,
|
||||
roleId: role?.id,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
LoggerProxy,
|
||||
NodeHelpers,
|
||||
} from 'n8n-workflow';
|
||||
import { FindConditions, FindManyOptions, In } from 'typeorm';
|
||||
import { FindManyOptions, FindOptionsWhere, In } from 'typeorm';
|
||||
|
||||
import * as Db from '@/Db';
|
||||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
|
@ -28,11 +28,12 @@ import { CredentialTypes } from '@/CredentialTypes';
|
|||
|
||||
export class CredentialsService {
|
||||
static async get(
|
||||
credential: Partial<ICredentialsDb>,
|
||||
where: FindOptionsWhere<ICredentialsDb>,
|
||||
options?: { relations: string[] },
|
||||
): Promise<ICredentialsDb | undefined> {
|
||||
return Db.collections.Credentials.findOne(credential, {
|
||||
): Promise<ICredentialsDb | null> {
|
||||
return Db.collections.Credentials.findOne({
|
||||
relations: options?.relations,
|
||||
where,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -88,8 +89,8 @@ export class CredentialsService {
|
|||
credentialId: string,
|
||||
relations: string[] = ['credentials'],
|
||||
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
||||
): Promise<SharedCredentials | undefined> {
|
||||
const where: FindConditions<SharedCredentials> = { credentialsId: credentialId };
|
||||
): Promise<SharedCredentials | null> {
|
||||
const where: FindOptionsWhere<SharedCredentials> = { credentialsId: credentialId };
|
||||
|
||||
// Omit user from where if the requesting user is the global
|
||||
// owner. This allows the global owner to view and delete
|
||||
|
@ -204,7 +205,7 @@ export class CredentialsService {
|
|||
static async update(
|
||||
credentialId: string,
|
||||
newCredentialData: ICredentialsDb,
|
||||
): Promise<ICredentialsDb | undefined> {
|
||||
): Promise<ICredentialsDb | null> {
|
||||
await ExternalHooks().run('credentials.update', [newCredentialData]);
|
||||
|
||||
// Update the credentials in DB
|
||||
|
@ -212,7 +213,7 @@ export class CredentialsService {
|
|||
|
||||
// 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.findOne(credentialId);
|
||||
return Db.collections.Credentials.findOneBy({ id: credentialId });
|
||||
}
|
||||
|
||||
static async save(
|
||||
|
@ -226,7 +227,7 @@ export class CredentialsService {
|
|||
|
||||
await ExternalHooks().run('credentials.create', [encryptedData]);
|
||||
|
||||
const role = await Db.collections.Role.findOneOrFail({
|
||||
const role = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Column, Entity, OneToMany, PrimaryGeneratedColumn, Unique } from 'typeorm';
|
||||
import { Column, Entity, OneToMany, PrimaryColumn, Unique } from 'typeorm';
|
||||
import { IsString, Length } from 'class-validator';
|
||||
|
||||
import type { User } from './User';
|
||||
import type { SharedWorkflow } from './SharedWorkflow';
|
||||
import type { SharedCredentials } from './SharedCredentials';
|
||||
import { AbstractEntity } from './AbstractEntity';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
|
||||
export type RoleNames = 'owner' | 'member' | 'user' | 'editor';
|
||||
export type RoleScopes = 'global' | 'workflow' | 'credential';
|
||||
|
@ -12,8 +13,8 @@ export type RoleScopes = 'global' | 'workflow' | 'credential';
|
|||
@Entity()
|
||||
@Unique(['scope', 'name'])
|
||||
export class Role extends AbstractEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
id: string;
|
||||
|
||||
@Column({ length: 32 })
|
||||
@IsString({ message: 'Role name must be of type string.' })
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Entity, ManyToOne, PrimaryColumn, RelationId } from 'typeorm';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import type { CredentialsEntity } from './CredentialsEntity';
|
||||
import type { User } from './User';
|
||||
import type { Role } from './Role';
|
||||
|
@ -10,20 +10,18 @@ export class SharedCredentials extends AbstractEntity {
|
|||
@ManyToOne('Role', 'sharedCredentials', { nullable: false })
|
||||
role: Role;
|
||||
|
||||
@ManyToOne('User', 'sharedCredentials', { primary: true })
|
||||
@Column()
|
||||
roleId: string;
|
||||
|
||||
@ManyToOne('User', 'sharedCredentials')
|
||||
user: User;
|
||||
|
||||
@PrimaryColumn()
|
||||
@RelationId((sharedCredential: SharedCredentials) => sharedCredential.user)
|
||||
userId: string;
|
||||
|
||||
@ManyToOne('CredentialsEntity', 'shared', {
|
||||
primary: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne('CredentialsEntity', 'shared')
|
||||
credentials: CredentialsEntity;
|
||||
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((sharedCredential: SharedCredentials) => sharedCredential.credentials)
|
||||
credentialsId: string;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Entity, ManyToOne, PrimaryColumn, RelationId } from 'typeorm';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import type { WorkflowEntity } from './WorkflowEntity';
|
||||
import type { User } from './User';
|
||||
import type { Role } from './Role';
|
||||
|
@ -10,20 +10,18 @@ export class SharedWorkflow extends AbstractEntity {
|
|||
@ManyToOne('Role', 'sharedWorkflows', { nullable: false })
|
||||
role: Role;
|
||||
|
||||
@ManyToOne('User', 'sharedWorkflows', { primary: true })
|
||||
@Column()
|
||||
roleId: string;
|
||||
|
||||
@ManyToOne('User', 'sharedWorkflows')
|
||||
user: User;
|
||||
|
||||
@PrimaryColumn()
|
||||
@RelationId((sharedWorkflow: SharedWorkflow) => sharedWorkflow.user)
|
||||
userId: string;
|
||||
|
||||
@ManyToOne('WorkflowEntity', 'shared', {
|
||||
primary: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne('WorkflowEntity', 'shared')
|
||||
workflow: WorkflowEntity;
|
||||
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((sharedWorkflow: SharedWorkflow) => sharedWorkflow.workflow)
|
||||
workflowId: string;
|
||||
}
|
||||
|
|
|
@ -74,12 +74,12 @@ export class User extends AbstractEntity implements IUser {
|
|||
})
|
||||
settings: IUserSettings | null;
|
||||
|
||||
@ManyToOne('Role', 'globalForUsers', {
|
||||
cascade: true,
|
||||
nullable: false,
|
||||
})
|
||||
@ManyToOne('Role', 'globalForUsers', { nullable: false })
|
||||
globalRole: Role;
|
||||
|
||||
@Column()
|
||||
globalRoleId: string;
|
||||
|
||||
@OneToMany('SharedWorkflow', 'user')
|
||||
sharedWorkflows: SharedWorkflow[];
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Column, Entity, RelationId, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { idStringifier } from '../utils/transformers';
|
||||
import { datetimeColumnType } from './AbstractEntity';
|
||||
import type { WorkflowEntity } from './WorkflowEntity';
|
||||
|
@ -22,13 +22,9 @@ export class WorkflowStatistics {
|
|||
@PrimaryColumn({ length: 128 })
|
||||
name: StatisticsNames;
|
||||
|
||||
@ManyToOne('WorkflowEntity', 'shared', {
|
||||
primary: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
@ManyToOne('WorkflowEntity', 'shared')
|
||||
workflow: WorkflowEntity;
|
||||
|
||||
@PrimaryColumn({ transformer: idStringifier })
|
||||
@RelationId((workflowStatistics: WorkflowStatistics) => workflowStatistics.workflow)
|
||||
workflowId: string;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { LoggerProxy, MessageEventBusDestinationOptions } from 'n8n-workflow';
|
||||
import { DeleteResult } from 'typeorm';
|
||||
import type { DeleteResult } from 'typeorm';
|
||||
import { EventMessageTypes } from '../EventMessageClasses/';
|
||||
import type { MessageEventBusDestination } from '../MessageEventBusDestination/MessageEventBusDestination.ee';
|
||||
import { MessageEventBusLogWriter } from '../MessageEventBusWriter/MessageEventBusLogWriter';
|
||||
|
|
|
@ -9,7 +9,7 @@ import * as Db from '@/Db';
|
|||
import { AbstractEventMessage } from '../EventMessageClasses/AbstractEventMessage';
|
||||
import { EventMessageTypes } from '../EventMessageClasses';
|
||||
import { eventBus } from '..';
|
||||
import { DeleteResult, InsertResult } from 'typeorm';
|
||||
import type { DeleteResult, InsertResult } from 'typeorm';
|
||||
|
||||
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.
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
jsonParse,
|
||||
Workflow,
|
||||
} from 'n8n-workflow';
|
||||
import { FindConditions, FindOperator, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm';
|
||||
import { FindOperator, FindOptionsWhere, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm';
|
||||
import * as ActiveExecutions from '@/ActiveExecutions';
|
||||
import config from '@/config';
|
||||
import type { User } from '@/databases/entities/User';
|
||||
|
@ -200,7 +200,7 @@ export class ExecutionsService {
|
|||
.map(({ id }) => id),
|
||||
);
|
||||
|
||||
const findWhere: FindConditions<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };
|
||||
const findWhere: FindOptionsWhere<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };
|
||||
|
||||
const rangeQuery: string[] = [];
|
||||
const rangeQueryParams: {
|
||||
|
@ -370,7 +370,9 @@ export class ExecutionsService {
|
|||
// Loads the currently saved workflow to execute instead of the
|
||||
// one saved at the time of the execution.
|
||||
const workflowId = fullExecutionData.workflowData.id as string;
|
||||
const workflowData = (await Db.collections.Workflow.findOne(workflowId)) as IWorkflowBase;
|
||||
const workflowData = (await Db.collections.Workflow.findOneBy({
|
||||
id: workflowId,
|
||||
})) as IWorkflowBase;
|
||||
|
||||
if (workflowData === undefined) {
|
||||
throw new Error(
|
||||
|
@ -453,7 +455,7 @@ export class ExecutionsService {
|
|||
throw new Error('Either "deleteBefore" or "ids" must be present in the request body');
|
||||
}
|
||||
|
||||
const where: FindConditions<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };
|
||||
const where: FindOptionsWhere<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };
|
||||
|
||||
if (deleteBefore) {
|
||||
// delete executions by date, if user may access the underlying workflows
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { EntityManager } from 'typeorm';
|
||||
import type { EntityManager, FindOptionsWhere } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import { Role } from '@db/entities/Role';
|
||||
|
||||
export class RoleService {
|
||||
static async get(role: Partial<Role>): Promise<Role | undefined> {
|
||||
return Db.collections.Role.findOne(role);
|
||||
static async get(role: FindOptionsWhere<Role>): Promise<Role | null> {
|
||||
return Db.collections.Role.findOneBy(role);
|
||||
}
|
||||
|
||||
static async trxGet(transaction: EntityManager, role: Partial<Role>) {
|
||||
return transaction.findOne(Role, role);
|
||||
static async trxGet(transaction: EntityManager, role: FindOptionsWhere<Role>) {
|
||||
return transaction.findOneBy(Role, role);
|
||||
}
|
||||
|
||||
static async getUserRoleForWorkflow(userId: string, workflowId: string) {
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { EntityManager, In } from 'typeorm';
|
||||
import { EntityManager, FindOptionsWhere, In } from 'typeorm';
|
||||
import * as Db from '@/Db';
|
||||
import { User } from '@db/entities/User';
|
||||
|
||||
export class UserService {
|
||||
static async get(user: Partial<User>): Promise<User | undefined> {
|
||||
return Db.collections.User.findOne(user, {
|
||||
static async get(where: FindOptionsWhere<User>): Promise<User | null> {
|
||||
return Db.collections.User.findOne({
|
||||
relations: ['globalRole'],
|
||||
where,
|
||||
});
|
||||
}
|
||||
|
||||
static async getByIds(transaction: EntityManager, ids: string[]) {
|
||||
return transaction.find(User, { id: In(ids) });
|
||||
return transaction.find(User, { where: { id: In(ids) } });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import * as TagHelpers from '@/TagHelpers';
|
|||
import { EECredentialsService as EECredentials } from '../credentials/credentials.service.ee';
|
||||
import { IExecutionPushResponse } from '@/Interfaces';
|
||||
import * as GenericHelpers from '@/GenericHelpers';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export const EEWorkflowController = express.Router();
|
||||
|
@ -130,8 +131,11 @@ EEWorkflowController.post(
|
|||
const { tags: tagIds } = req.body;
|
||||
|
||||
if (tagIds?.length && !config.getEnv('workflowTagsDisabled')) {
|
||||
newWorkflow.tags = await Db.collections.Tag.findByIds(tagIds, {
|
||||
newWorkflow.tags = await Db.collections.Tag.find({
|
||||
select: ['id', 'name'],
|
||||
where: {
|
||||
id: In(tagIds),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -157,7 +161,7 @@ EEWorkflowController.post(
|
|||
await Db.transaction(async (transactionManager) => {
|
||||
savedWorkflow = await transactionManager.save<WorkflowEntity>(newWorkflow);
|
||||
|
||||
const role = await Db.collections.Role.findOneOrFail({
|
||||
const role = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
|
|
@ -23,6 +23,7 @@ import { isBelowOnboardingThreshold } from '@/WorkflowHelpers';
|
|||
import { EEWorkflowController } from './workflows.controller.ee';
|
||||
import { WorkflowsService } from './workflows.services';
|
||||
import { whereClause } from '@/UserManagement/UserManagementHelper';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
export const workflowsController = express.Router();
|
||||
|
||||
|
@ -61,8 +62,11 @@ workflowsController.post(
|
|||
const { tags: tagIds } = req.body;
|
||||
|
||||
if (tagIds?.length && !config.getEnv('workflowTagsDisabled')) {
|
||||
newWorkflow.tags = await Db.collections.Tag.findByIds(tagIds, {
|
||||
newWorkflow.tags = await Db.collections.Tag.find({
|
||||
select: ['id', 'name'],
|
||||
where: {
|
||||
id: In(tagIds),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -75,7 +79,7 @@ workflowsController.post(
|
|||
await Db.transaction(async (transactionManager) => {
|
||||
savedWorkflow = await transactionManager.save<WorkflowEntity>(newWorkflow);
|
||||
|
||||
const role = await Db.collections.Role.findOneOrFail({
|
||||
const role = await Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
|
|
|
@ -74,13 +74,12 @@ export class EEWorkflowsService extends WorkflowsService {
|
|||
if (user.isPending) {
|
||||
return acc;
|
||||
}
|
||||
acc.push(
|
||||
Db.collections.SharedWorkflow.create({
|
||||
workflow,
|
||||
user,
|
||||
role,
|
||||
}),
|
||||
);
|
||||
const entity: Partial<SharedWorkflow> = {
|
||||
workflowId: workflow.id,
|
||||
userId: user.id,
|
||||
roleId: role?.id,
|
||||
};
|
||||
acc.push(Db.collections.SharedWorkflow.create(entity));
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { validate as jsonSchemaValidate } from 'jsonschema';
|
||||
import { INode, IPinData, JsonObject, jsonParse, LoggerProxy, Workflow } from 'n8n-workflow';
|
||||
import { FindConditions, In } from 'typeorm';
|
||||
import { FindOptionsWhere, In } from 'typeorm';
|
||||
import pick from 'lodash.pick';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import * as ActiveWorkflowRunner from '@/ActiveWorkflowRunner';
|
||||
|
@ -48,8 +48,8 @@ export class WorkflowsService {
|
|||
workflowId: string,
|
||||
relations: string[] = ['workflow'],
|
||||
{ allowGlobalOwner } = { allowGlobalOwner: true },
|
||||
): Promise<SharedWorkflow | undefined> {
|
||||
const where: FindConditions<SharedWorkflow> = { workflowId };
|
||||
): Promise<SharedWorkflow | null> {
|
||||
const where: FindOptionsWhere<SharedWorkflow> = { workflowId };
|
||||
|
||||
// Omit user from where if the requesting user is the global
|
||||
// owner. This allows the global owner to view and delete
|
||||
|
@ -103,8 +103,8 @@ export class WorkflowsService {
|
|||
return pinnedTriggers.find((pt) => pt.name === checkNodeName) ?? null; // partial execution
|
||||
}
|
||||
|
||||
static async get(workflow: Partial<WorkflowEntity>, options?: { relations: string[] }) {
|
||||
return Db.collections.Workflow.findOne(workflow, options);
|
||||
static async get(workflow: FindOptionsWhere<WorkflowEntity>, options?: { relations: string[] }) {
|
||||
return Db.collections.Workflow.findOne({ where: workflow, relations: options?.relations });
|
||||
}
|
||||
|
||||
// Warning: this function is overridden by EE to disregard role list.
|
||||
|
@ -299,9 +299,12 @@ 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(workflowId, { relations });
|
||||
const updatedWorkflow = await Db.collections.Workflow.findOne({
|
||||
where: { id: workflowId },
|
||||
relations,
|
||||
});
|
||||
|
||||
if (updatedWorkflow === undefined) {
|
||||
if (updatedWorkflow === null) {
|
||||
throw new ResponseHelper.BadRequestError(
|
||||
`Workflow with ID "${workflowId}" could not be found to be updated.`,
|
||||
);
|
||||
|
|
|
@ -6,19 +6,16 @@ import { CREDENTIALS_REPORT } from '@/audit/constants';
|
|||
import { getRiskSection } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let testDbName = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow', 'Credentials', 'Execution'], testDbName);
|
||||
await testDb.truncate(['Workflow', 'Credentials', 'Execution']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should report credentials not in any use', async () => {
|
||||
|
|
|
@ -9,19 +9,16 @@ import {
|
|||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let testDbName = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow'], testDbName);
|
||||
await testDb.truncate(['Workflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should report expressions in queries', async () => {
|
||||
|
|
|
@ -5,19 +5,16 @@ import { FILESYSTEM_INTERACTION_NODE_TYPES, FILESYSTEM_REPORT } from '@/audit/co
|
|||
import { getRiskSection, saveManualTriggerWorkflow } from './utils';
|
||||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let testDbName = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow'], testDbName);
|
||||
await testDb.truncate(['Workflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should report filesystem interaction nodes', async () => {
|
||||
|
|
|
@ -13,21 +13,18 @@ import * as testDb from '../shared/testDb';
|
|||
import { toReportTitle } from '@/audit/utils';
|
||||
import config from '@/config';
|
||||
|
||||
let testDbName = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
simulateUpToDateInstance();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow'], testDbName);
|
||||
await testDb.truncate(['Workflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should report webhook lacking authentication', async () => {
|
||||
|
|
|
@ -7,19 +7,16 @@ import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils
|
|||
import * as testDb from '../shared/testDb';
|
||||
import { toReportTitle } from '@/audit/utils';
|
||||
|
||||
let testDbName = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['Workflow'], testDbName);
|
||||
await testDb.truncate(['Workflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('should report risky official nodes', async () => {
|
||||
|
|
|
@ -11,15 +11,13 @@ import type { AuthAgent } from './shared/types';
|
|||
import * as utils from './shared/utils';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['auth'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
@ -31,7 +29,7 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
|
||||
config.set('userManagement.isInstanceOwnerSetUp', true);
|
||||
|
||||
|
@ -42,7 +40,7 @@ beforeEach(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('POST /login should log user in', async () => {
|
||||
|
|
|
@ -12,7 +12,6 @@ import type { AuthAgent } from './shared/types';
|
|||
import * as utils from './shared/utils';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalMemberRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
||||
|
@ -21,8 +20,7 @@ beforeAll(async () => {
|
|||
applyAuth: true,
|
||||
endpointGroups: ['me', 'auth', 'owner', 'users'],
|
||||
});
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
||||
|
@ -33,7 +31,7 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
ROUTES_REQUIRING_AUTHENTICATION.concat(ROUTES_REQUIRING_AUTHORIZATION).forEach((route) => {
|
||||
|
|
|
@ -7,23 +7,21 @@ import * as utils from '../shared/utils';
|
|||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['owner'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('user-management:reset should reset DB to default user state', async () => {
|
||||
|
@ -31,7 +29,7 @@ test('user-management:reset should reset DB to default user state', async () =>
|
|||
|
||||
await Reset.run();
|
||||
|
||||
const user = await Db.collections.User.findOne({ globalRole: globalOwnerRole });
|
||||
const user = await Db.collections.User.findOneBy({ globalRoleId: globalOwnerRole.id });
|
||||
|
||||
if (!user) {
|
||||
fail('No owner found after DB reset to default user state');
|
||||
|
|
|
@ -14,7 +14,6 @@ import * as utils from './shared/utils';
|
|||
import type { IUser } from 'n8n-workflow';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let credentialOwnerRole: Role;
|
||||
|
@ -27,8 +26,7 @@ beforeAll(async () => {
|
|||
endpointGroups: ['credentials'],
|
||||
applyAuth: true,
|
||||
});
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
utils.initConfigFile();
|
||||
|
||||
|
@ -46,11 +44,11 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials'], testDbName);
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
// ----------------------------------------
|
||||
|
@ -380,7 +378,7 @@ test('PUT /credentials/:id/share should share the credential with the provided u
|
|||
|
||||
const sharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
relations: ['role'],
|
||||
where: { credentials: savedCredential },
|
||||
where: { credentialsId: savedCredential.id },
|
||||
});
|
||||
|
||||
// check that sharings have been removed/added correctly
|
||||
|
@ -420,7 +418,7 @@ test('PUT /credentials/:id/share should share the credential with the provided u
|
|||
// check that sharings got correctly set in DB
|
||||
const sharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
relations: ['role'],
|
||||
where: { credentials: savedCredential, user: { id: In([...memberIds]) } },
|
||||
where: { credentialsId: savedCredential.id, userId: In([...memberIds]) },
|
||||
});
|
||||
|
||||
expect(sharedCredentials.length).toBe(memberIds.length);
|
||||
|
@ -433,7 +431,7 @@ test('PUT /credentials/:id/share should share the credential with the provided u
|
|||
// check that owner still exists
|
||||
const ownerSharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['role'],
|
||||
where: { credentials: savedCredential, user: owner },
|
||||
where: { credentialsId: savedCredential.id, userId: owner.id },
|
||||
});
|
||||
|
||||
expect(ownerSharedCredential.role.name).toBe('owner');
|
||||
|
@ -475,7 +473,7 @@ test('PUT /credentials/:id/share should ignore pending sharee', async () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const sharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
where: { credentials: savedCredential },
|
||||
where: { credentialsId: savedCredential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredentials).toHaveLength(1);
|
||||
|
@ -493,7 +491,7 @@ test('PUT /credentials/:id/share should ignore non-existing sharee', async () =>
|
|||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const sharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
where: { credentials: savedCredential },
|
||||
where: { credentialsId: savedCredential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredentials).toHaveLength(1);
|
||||
|
@ -535,7 +533,7 @@ test('PUT /credentials/:id/share should unshare the credential', async () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const sharedCredentials = await Db.collections.SharedCredentials.find({
|
||||
where: { credentials: savedCredential },
|
||||
where: { credentialsId: savedCredential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredentials).toHaveLength(1);
|
||||
|
|
|
@ -19,7 +19,6 @@ const mockIsCredentialsSharingEnabled = jest.spyOn(UserManagementHelpers, 'isSha
|
|||
mockIsCredentialsSharingEnabled.mockReturnValue(false);
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let saveCredential: SaveCredentialFunction;
|
||||
|
@ -30,8 +29,7 @@ beforeAll(async () => {
|
|||
endpointGroups: ['credentials'],
|
||||
applyAuth: true,
|
||||
});
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
utils.initConfigFile();
|
||||
|
||||
|
@ -48,11 +46,11 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials'], testDbName);
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
// ----------------------------------------
|
||||
|
@ -124,7 +122,7 @@ test('POST /credentials should create cred', async () => {
|
|||
expect(nodesAccess[0].nodeType).toBe(payload.nodesAccess[0].nodeType);
|
||||
expect(encryptedData).not.toBe(payload.data);
|
||||
|
||||
const credential = await Db.collections.Credentials.findOneOrFail(id);
|
||||
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
|
||||
|
||||
expect(credential.name).toBe(payload.name);
|
||||
expect(credential.type).toBe(payload.type);
|
||||
|
@ -133,7 +131,7 @@ test('POST /credentials should create cred', async () => {
|
|||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['user', 'credentials'],
|
||||
where: { credentials: credential },
|
||||
where: { credentialsId: credential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.user.id).toBe(ownerShell.id);
|
||||
|
@ -191,13 +189,13 @@ test('DELETE /credentials/:id should delete owned cred for owner', async () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual({ data: true });
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should delete non-owned cred for owner', async () => {
|
||||
|
@ -210,13 +208,13 @@ test('DELETE /credentials/:id should delete non-owned cred for owner', async ()
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual({ data: true });
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should delete owned cred for member', async () => {
|
||||
|
@ -228,13 +226,13 @@ test('DELETE /credentials/:id should delete owned cred for member', async () =>
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual({ data: true });
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should not delete non-owned cred for member', async () => {
|
||||
|
@ -246,11 +244,11 @@ test('DELETE /credentials/:id should not delete non-owned cred for member', asyn
|
|||
|
||||
expect(response.statusCode).toBe(404);
|
||||
|
||||
const shellCredential = await Db.collections.Credentials.findOne(savedCredential.id);
|
||||
const shellCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(shellCredential).toBeDefined(); // not deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeDefined(); // not deleted
|
||||
});
|
||||
|
@ -285,7 +283,7 @@ test('PATCH /credentials/:id should update owned cred for owner', async () => {
|
|||
|
||||
expect(encryptedData).not.toBe(patchPayload.data);
|
||||
|
||||
const credential = await Db.collections.Credentials.findOneOrFail(id);
|
||||
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
|
||||
|
||||
expect(credential.name).toBe(patchPayload.name);
|
||||
expect(credential.type).toBe(patchPayload.type);
|
||||
|
@ -294,7 +292,7 @@ test('PATCH /credentials/:id should update owned cred for owner', async () => {
|
|||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { credentials: credential },
|
||||
where: { credentialsId: credential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.credentials.name).toBe(patchPayload.name); // updated
|
||||
|
@ -324,7 +322,7 @@ test('PATCH /credentials/:id should update non-owned cred for owner', async () =
|
|||
|
||||
expect(encryptedData).not.toBe(patchPayload.data);
|
||||
|
||||
const credential = await Db.collections.Credentials.findOneOrFail(id);
|
||||
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
|
||||
|
||||
expect(credential.name).toBe(patchPayload.name);
|
||||
expect(credential.type).toBe(patchPayload.type);
|
||||
|
@ -333,7 +331,7 @@ test('PATCH /credentials/:id should update non-owned cred for owner', async () =
|
|||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { credentials: credential },
|
||||
where: { credentialsId: credential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.credentials.name).toBe(patchPayload.name); // updated
|
||||
|
@ -362,7 +360,7 @@ test('PATCH /credentials/:id should update owned cred for member', async () => {
|
|||
|
||||
expect(encryptedData).not.toBe(patchPayload.data);
|
||||
|
||||
const credential = await Db.collections.Credentials.findOneOrFail(id);
|
||||
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
|
||||
|
||||
expect(credential.name).toBe(patchPayload.name);
|
||||
expect(credential.type).toBe(patchPayload.type);
|
||||
|
@ -371,7 +369,7 @@ test('PATCH /credentials/:id should update owned cred for member', async () => {
|
|||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { credentials: credential },
|
||||
where: { credentialsId: credential.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.credentials.name).toBe(patchPayload.name); // updated
|
||||
|
@ -389,7 +387,9 @@ test('PATCH /credentials/:id should not update non-owned cred for member', async
|
|||
|
||||
expect(response.statusCode).toBe(404);
|
||||
|
||||
const shellCredential = await Db.collections.Credentials.findOneOrFail(savedCredential.id);
|
||||
const shellCredential = await Db.collections.Credentials.findOneByOrFail({
|
||||
id: savedCredential.id,
|
||||
});
|
||||
|
||||
expect(shellCredential.name).not.toBe(patchPayload.name); // not updated
|
||||
});
|
||||
|
|
|
@ -16,11 +16,11 @@ import {
|
|||
} from 'n8n-workflow';
|
||||
import { eventBus } from '@/eventbus';
|
||||
import { SuperAgentTest } from 'supertest';
|
||||
import { EventMessageGeneric } from '../../src/eventbus/EventMessageClasses/EventMessageGeneric';
|
||||
import { MessageEventBusDestinationSyslog } from '../../src/eventbus/MessageEventBusDestination/MessageEventBusDestinationSyslog.ee';
|
||||
import { MessageEventBusDestinationWebhook } from '../../src/eventbus/MessageEventBusDestination/MessageEventBusDestinationWebhook.ee';
|
||||
import { MessageEventBusDestinationSentry } from '../../src/eventbus/MessageEventBusDestination/MessageEventBusDestinationSentry.ee';
|
||||
import { EventMessageAudit } from '../../src/eventbus/EventMessageClasses/EventMessageAudit';
|
||||
import { EventMessageGeneric } from '@/eventbus/EventMessageClasses/EventMessageGeneric';
|
||||
import { MessageEventBusDestinationSyslog } from '@/eventbus/MessageEventBusDestination/MessageEventBusDestinationSyslog.ee';
|
||||
import { MessageEventBusDestinationWebhook } from '@/eventbus/MessageEventBusDestination/MessageEventBusDestinationWebhook.ee';
|
||||
import { MessageEventBusDestinationSentry } from '@/eventbus/MessageEventBusDestination/MessageEventBusDestinationSentry.ee';
|
||||
import { EventMessageAudit } from '@/eventbus/EventMessageClasses/EventMessageAudit';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
jest.unmock('@/eventbus/MessageEventBus/MessageEventBus');
|
||||
|
@ -30,7 +30,6 @@ jest.mock('syslog-client');
|
|||
const mockedSyslog = syslog as jest.Mocked<typeof syslog>;
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let owner: User;
|
||||
let unAuthOwnerAgent: SuperAgentTest;
|
||||
|
@ -82,8 +81,7 @@ async function confirmIdSent(id: string) {
|
|||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
owner = await testDb.createUser({ globalRole: globalOwnerRole });
|
||||
|
||||
|
@ -121,7 +119,7 @@ beforeEach(async () => {
|
|||
|
||||
afterAll(async () => {
|
||||
jest.mock('@/eventbus/MessageEventBus/MessageEventBus');
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
await eventBus.close();
|
||||
});
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ const MOCK_RENEW_OFFSET = 259200;
|
|||
const MOCK_INSTANCE_ID = 'instance-id';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
@ -21,8 +20,7 @@ let license: License;
|
|||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['license'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
@ -43,11 +41,11 @@ beforeEach(async () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await testDb.truncate(['Settings'], testDbName);
|
||||
await testDb.truncate(['Settings']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('GET /license should return license information to the instance owner', async () => {
|
||||
|
|
|
@ -18,15 +18,13 @@ import type { AuthAgent } from './shared/types';
|
|||
import * as utils from './shared/utils';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['me'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
@ -38,12 +36,12 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
describe('Owner shell', () => {
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
test('GET /me should return sanitized owner shell', async () => {
|
||||
|
@ -113,7 +111,7 @@ describe('Owner shell', () => {
|
|||
expect(globalRole.scope).toBe('global');
|
||||
expect(apiKey).toBeUndefined();
|
||||
|
||||
const storedOwnerShell = await Db.collections.User.findOneOrFail(id);
|
||||
const storedOwnerShell = await Db.collections.User.findOneByOrFail({ id });
|
||||
|
||||
expect(storedOwnerShell.email).toBe(validPayload.email.toLowerCase());
|
||||
expect(storedOwnerShell.firstName).toBe(validPayload.firstName);
|
||||
|
@ -129,7 +127,7 @@ describe('Owner shell', () => {
|
|||
const response = await authOwnerShellAgent.patch('/me').send(invalidPayload);
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const storedOwnerShell = await Db.collections.User.findOneOrFail();
|
||||
const storedOwnerShell = await Db.collections.User.findOneByOrFail({});
|
||||
expect(storedOwnerShell.email).toBeNull();
|
||||
expect(storedOwnerShell.firstName).toBeNull();
|
||||
expect(storedOwnerShell.lastName).toBeNull();
|
||||
|
@ -152,7 +150,7 @@ describe('Owner shell', () => {
|
|||
const response = await authOwnerShellAgent.patch('/me/password').send(payload);
|
||||
expect([400, 500].includes(response.statusCode)).toBe(true);
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail();
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({});
|
||||
|
||||
if (payload.newPassword) {
|
||||
expect(storedMember.password).not.toBe(payload.newPassword);
|
||||
|
@ -164,7 +162,7 @@ describe('Owner shell', () => {
|
|||
}),
|
||||
);
|
||||
|
||||
const storedOwnerShell = await Db.collections.User.findOneOrFail();
|
||||
const storedOwnerShell = await Db.collections.User.findOneByOrFail({});
|
||||
expect(storedOwnerShell.password).toBeNull();
|
||||
});
|
||||
|
||||
|
@ -241,7 +239,7 @@ describe('Member', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
test('GET /me should return sanitized member', async () => {
|
||||
|
@ -311,7 +309,7 @@ describe('Member', () => {
|
|||
expect(globalRole.scope).toBe('global');
|
||||
expect(apiKey).toBeUndefined();
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail(id);
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({ id });
|
||||
|
||||
expect(storedMember.email).toBe(validPayload.email.toLowerCase());
|
||||
expect(storedMember.firstName).toBe(validPayload.firstName);
|
||||
|
@ -327,7 +325,7 @@ describe('Member', () => {
|
|||
const response = await authMemberAgent.patch('/me').send(invalidPayload);
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail();
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({});
|
||||
expect(storedMember.email).toBe(member.email);
|
||||
expect(storedMember.firstName).toBe(member.firstName);
|
||||
expect(storedMember.lastName).toBe(member.lastName);
|
||||
|
@ -350,7 +348,7 @@ describe('Member', () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail();
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({});
|
||||
expect(storedMember.password).not.toBe(member.password);
|
||||
expect(storedMember.password).not.toBe(validPayload.newPassword);
|
||||
});
|
||||
|
@ -363,7 +361,7 @@ describe('Member', () => {
|
|||
const response = await authMemberAgent.patch('/me/password').send(payload);
|
||||
expect([400, 500].includes(response.statusCode)).toBe(true);
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail();
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({});
|
||||
|
||||
if (payload.newPassword) {
|
||||
expect(storedMember.password).not.toBe(payload.newPassword);
|
||||
|
@ -385,7 +383,9 @@ describe('Member', () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
|
||||
|
||||
const { personalizationAnswers: storedAnswers } = await Db.collections.User.findOneOrFail();
|
||||
const { personalizationAnswers: storedAnswers } = await Db.collections.User.findOneByOrFail(
|
||||
{},
|
||||
);
|
||||
|
||||
expect(storedAnswers).toEqual(validPayload);
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ describe('Member', () => {
|
|||
expect(response.body.data.apiKey).toBeDefined();
|
||||
expect(response.body.data.apiKey).not.toBeNull();
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail(member.id);
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({ id: member.id });
|
||||
|
||||
expect(storedMember.apiKey).toEqual(response.body.data.apiKey);
|
||||
});
|
||||
|
@ -430,7 +430,7 @@ describe('Member', () => {
|
|||
|
||||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const storedMember = await Db.collections.User.findOneOrFail(member.id);
|
||||
const storedMember = await Db.collections.User.findOneByOrFail({ id: member.id });
|
||||
|
||||
expect(storedMember.apiKey).toBeNull();
|
||||
});
|
||||
|
@ -442,7 +442,7 @@ describe('Owner', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
test('GET /me should return sanitized owner', async () => {
|
||||
|
@ -512,7 +512,7 @@ describe('Owner', () => {
|
|||
expect(globalRole.scope).toBe('global');
|
||||
expect(apiKey).toBeUndefined();
|
||||
|
||||
const storedOwner = await Db.collections.User.findOneOrFail(id);
|
||||
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
|
||||
|
||||
expect(storedOwner.email).toBe(validPayload.email.toLowerCase());
|
||||
expect(storedOwner.firstName).toBe(validPayload.firstName);
|
||||
|
|
|
@ -43,14 +43,12 @@ jest.mock('@/CommunityNodes/packageModel', () => {
|
|||
const mockedEmptyPackage = mocked(utils.emptyPackage);
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['nodes'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
|
||||
|
@ -62,14 +60,14 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['InstalledNodes', 'InstalledPackages', 'User'], testDbName);
|
||||
await testDb.truncate(['InstalledNodes', 'InstalledPackages', 'User']);
|
||||
|
||||
mocked(executeCommand).mockReset();
|
||||
mocked(findInstalledPackage).mockReset();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,14 +15,12 @@ import type { AuthAgent } from './shared/types';
|
|||
import * as utils from './shared/utils';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let authAgent: AuthAgent;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['owner'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
|
||||
|
@ -37,11 +35,11 @@ beforeEach(async () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('POST /owner should create owner and enable isInstanceOwnerSetUp', async () => {
|
||||
|
@ -83,7 +81,7 @@ test('POST /owner should create owner and enable isInstanceOwnerSetUp', async ()
|
|||
expect(globalRole.scope).toBe('global');
|
||||
expect(apiKey).toBeUndefined();
|
||||
|
||||
const storedOwner = await Db.collections.User.findOneOrFail(id);
|
||||
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
|
||||
expect(storedOwner.password).not.toBe(newOwnerData.password);
|
||||
expect(storedOwner.email).toBe(newOwnerData.email);
|
||||
expect(storedOwner.firstName).toBe(newOwnerData.firstName);
|
||||
|
@ -115,7 +113,7 @@ test('POST /owner should create owner with lowercased email', async () => {
|
|||
expect(id).toBe(ownerShell.id);
|
||||
expect(email).toBe(newOwnerData.email.toLowerCase());
|
||||
|
||||
const storedOwner = await Db.collections.User.findOneOrFail(id);
|
||||
const storedOwner = await Db.collections.User.findOneByOrFail({ id });
|
||||
expect(storedOwner.email).toBe(newOwnerData.email.toLowerCase());
|
||||
});
|
||||
|
||||
|
@ -141,7 +139,7 @@ test('POST /owner/skip-setup should persist skipping setup to the DB', async ()
|
|||
const skipConfig = config.getEnv('userManagement.skipInstanceOwnerSetup');
|
||||
expect(skipConfig).toBe(true);
|
||||
|
||||
const { value } = await Db.collections.Settings.findOneOrFail({
|
||||
const { value } = await Db.collections.Settings.findOneByOrFail({
|
||||
key: 'userManagement.skipInstanceOwnerSetup',
|
||||
});
|
||||
expect(value).toBe('true');
|
||||
|
|
|
@ -17,14 +17,12 @@ import type { Role } from '@db/entities/Role';
|
|||
jest.mock('@/UserManagement/email/NodeMailer');
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['passwordReset'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
@ -34,7 +32,7 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User'], testDbName);
|
||||
await testDb.truncate(['User']);
|
||||
|
||||
jest.mock('@/config');
|
||||
|
||||
|
@ -43,7 +41,7 @@ beforeEach(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('POST /forgot-password should send password reset email', async () => {
|
||||
|
@ -64,7 +62,7 @@ test('POST /forgot-password should send password reset email', async () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual({});
|
||||
|
||||
const user = await Db.collections.User.findOneOrFail({ email: payload.email });
|
||||
const user = await Db.collections.User.findOneByOrFail({ email: payload.email });
|
||||
expect(user.resetPasswordToken).toBeDefined();
|
||||
expect(user.resetPasswordTokenExpiration).toBeGreaterThan(Math.ceil(Date.now() / 1000));
|
||||
}),
|
||||
|
@ -80,7 +78,7 @@ test('POST /forgot-password should fail if emailing is not set up', async () =>
|
|||
|
||||
expect(response.statusCode).toBe(500);
|
||||
|
||||
const storedOwner = await Db.collections.User.findOneOrFail({ email: owner.email });
|
||||
const storedOwner = await Db.collections.User.findOneByOrFail({ email: owner.email });
|
||||
expect(storedOwner.resetPasswordToken).toBeNull();
|
||||
});
|
||||
|
||||
|
@ -104,7 +102,7 @@ test('POST /forgot-password should fail with invalid inputs', async () => {
|
|||
const response = await authlessAgent.post('/forgot-password').send(invalidPayload);
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const storedOwner = await Db.collections.User.findOneOrFail({ email: owner.email });
|
||||
const storedOwner = await Db.collections.User.findOneByOrFail({ email: owner.email });
|
||||
expect(storedOwner.resetPasswordToken).toBeNull();
|
||||
}),
|
||||
);
|
||||
|
@ -218,7 +216,7 @@ test('POST /change-password should succeed with valid inputs', async () => {
|
|||
const authToken = utils.getAuthToken(response);
|
||||
expect(authToken).toBeDefined();
|
||||
|
||||
const { password: storedPassword } = await Db.collections.User.findOneOrFail(owner.id);
|
||||
const { password: storedPassword } = await Db.collections.User.findOneByOrFail({ id: owner.id });
|
||||
|
||||
const comparisonResult = await compare(passwordToStore, storedPassword);
|
||||
expect(comparisonResult).toBe(true);
|
||||
|
@ -262,7 +260,7 @@ test('POST /change-password should fail with invalid inputs', async () => {
|
|||
const response = await authlessAgent.post('/change-password').query(invalidPayload);
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const { password: storedPassword } = await Db.collections.User.findOneOrFail();
|
||||
const { password: storedPassword } = await Db.collections.User.findOneByOrFail({});
|
||||
expect(owner.password).toBe(storedPassword);
|
||||
}),
|
||||
);
|
||||
|
|
|
@ -11,7 +11,6 @@ import type { CredentialPayload, SaveCredentialFunction } from '../shared/types'
|
|||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let credentialOwnerRole: Role;
|
||||
|
@ -20,8 +19,7 @@ let saveCredential: SaveCredentialFunction;
|
|||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
utils.initConfigFile();
|
||||
|
||||
|
@ -40,11 +38,11 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials'], testDbName);
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'Credentials']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('POST /credentials should create credentials', async () => {
|
||||
|
@ -76,15 +74,15 @@ test('POST /credentials should create credentials', async () => {
|
|||
expect(name).toBe(payload.name);
|
||||
expect(type).toBe(payload.type);
|
||||
|
||||
const credential = await Db.collections.Credentials!.findOneOrFail(id);
|
||||
const credential = await Db.collections.Credentials.findOneByOrFail({ id });
|
||||
|
||||
expect(credential.name).toBe(payload.name);
|
||||
expect(credential.type).toBe(payload.type);
|
||||
expect(credential.data).not.toBe(payload.data);
|
||||
|
||||
const sharedCredential = await Db.collections.SharedCredentials!.findOneOrFail({
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['user', 'credentials', 'role'],
|
||||
where: { credentials: credential, user: ownerShell },
|
||||
where: { credentialsId: credential.id, userId: ownerShell.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.role).toEqual(credentialOwnerRole);
|
||||
|
@ -153,13 +151,13 @@ test('DELETE /credentials/:id should delete owned cred for owner', async () => {
|
|||
expect(name).toBe(savedCredential.name);
|
||||
expect(type).toBe(savedCredential.type);
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials!.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials!.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should delete non-owned cred for owner', async () => {
|
||||
|
@ -181,13 +179,13 @@ test('DELETE /credentials/:id should delete non-owned cred for owner', async ()
|
|||
|
||||
expect(response.statusCode).toBe(200);
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials!.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials!.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should delete owned cred for member', async () => {
|
||||
|
@ -211,13 +209,13 @@ test('DELETE /credentials/:id should delete owned cred for member', async () =>
|
|||
expect(name).toBe(savedCredential.name);
|
||||
expect(type).toBe(savedCredential.type);
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials!.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials!.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /credentials/:id should delete owned cred for member but leave others untouched', async () => {
|
||||
|
@ -244,27 +242,27 @@ test('DELETE /credentials/:id should delete owned cred for member but leave othe
|
|||
expect(name).toBe(savedCredential.name);
|
||||
expect(type).toBe(savedCredential.type);
|
||||
|
||||
const deletedCredential = await Db.collections.Credentials!.findOne(savedCredential.id);
|
||||
const deletedCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(deletedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedCredential).toBeNull(); // deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials!.findOne({
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOne({
|
||||
where: {
|
||||
credentials: savedCredential,
|
||||
credentialsId: savedCredential.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(deletedSharedCredential).toBeUndefined(); // deleted
|
||||
expect(deletedSharedCredential).toBeNull(); // deleted
|
||||
|
||||
await Promise.all(
|
||||
[notToBeChangedCredential, notToBeChangedCredential2].map(async (credential) => {
|
||||
const untouchedCredential = await Db.collections.Credentials!.findOne(credential.id);
|
||||
const untouchedCredential = await Db.collections.Credentials.findOneBy({ id: credential.id });
|
||||
|
||||
expect(untouchedCredential).toEqual(credential); // not deleted
|
||||
|
||||
const untouchedSharedCredential = await Db.collections.SharedCredentials!.findOne({
|
||||
const untouchedSharedCredential = await Db.collections.SharedCredentials.findOne({
|
||||
where: {
|
||||
credentials: credential,
|
||||
credentialsId: credential.id,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -289,11 +287,11 @@ test('DELETE /credentials/:id should not delete non-owned cred for member', asyn
|
|||
|
||||
expect(response.statusCode).toBe(404);
|
||||
|
||||
const shellCredential = await Db.collections.Credentials!.findOne(savedCredential.id);
|
||||
const shellCredential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
|
||||
expect(shellCredential).toBeDefined(); // not deleted
|
||||
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials!.findOne();
|
||||
const deletedSharedCredential = await Db.collections.SharedCredentials.findOneBy({});
|
||||
|
||||
expect(deletedSharedCredential).toBeDefined(); // not deleted
|
||||
});
|
||||
|
|
|
@ -9,14 +9,12 @@ import * as utils from '../shared/utils';
|
|||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let workflowRunner: ActiveWorkflowRunner;
|
||||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
|
||||
|
@ -30,18 +28,15 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(
|
||||
[
|
||||
'SharedCredentials',
|
||||
'SharedWorkflow',
|
||||
'User',
|
||||
'Workflow',
|
||||
'Credentials',
|
||||
'Execution',
|
||||
'Settings',
|
||||
],
|
||||
testDbName,
|
||||
);
|
||||
await testDb.truncate([
|
||||
'SharedCredentials',
|
||||
'SharedWorkflow',
|
||||
'User',
|
||||
'Workflow',
|
||||
'Credentials',
|
||||
'Execution',
|
||||
'Settings',
|
||||
]);
|
||||
|
||||
config.set('userManagement.disabled', false);
|
||||
config.set('userManagement.isInstanceOwnerSetUp', true);
|
||||
|
@ -52,7 +47,7 @@ afterEach(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('GET /executions/:id should fail due to missing API Key', async () => {
|
||||
|
|
|
@ -11,7 +11,6 @@ import * as utils from '../shared/utils';
|
|||
import * as testDb from '../shared/testDb';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let workflowOwnerRole: Role;
|
||||
|
@ -19,8 +18,7 @@ let workflowRunner: ActiveWorkflowRunner;
|
|||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['publicApi'], applyAuth: false });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
const [fetchedGlobalOwnerRole, fetchedGlobalMemberRole, fetchedWorkflowOwnerRole] =
|
||||
await testDb.getAllRoles();
|
||||
|
@ -37,10 +35,14 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(
|
||||
['SharedCredentials', 'SharedWorkflow', 'Tag', 'User', 'Workflow', 'Credentials'],
|
||||
testDbName,
|
||||
);
|
||||
await testDb.truncate([
|
||||
'SharedCredentials',
|
||||
'SharedWorkflow',
|
||||
'Tag',
|
||||
'User',
|
||||
'Workflow',
|
||||
'Credentials',
|
||||
]);
|
||||
|
||||
config.set('userManagement.disabled', false);
|
||||
config.set('userManagement.isInstanceOwnerSetUp', true);
|
||||
|
@ -51,7 +53,7 @@ afterEach(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('GET /workflows should fail due to missing API Key', async () => {
|
||||
|
@ -537,11 +539,11 @@ test('DELETE /workflows/:id should delete the workflow', async () => {
|
|||
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
|
||||
|
||||
// make sure the workflow actually deleted from the db
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
workflow,
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneBy({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
|
||||
expect(sharedWorkflow).toBeUndefined();
|
||||
expect(sharedWorkflow).toBeNull();
|
||||
});
|
||||
|
||||
test('DELETE /workflows/:id should delete non-owned workflow when owner', async () => {
|
||||
|
@ -576,11 +578,11 @@ test('DELETE /workflows/:id should delete non-owned workflow when owner', async
|
|||
expect(updatedAt).toEqual(workflow.updatedAt.toISOString());
|
||||
|
||||
// make sure the workflow actually deleted from the db
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
workflow,
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneBy({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
|
||||
expect(sharedWorkflow).toBeUndefined();
|
||||
expect(sharedWorkflow).toBeNull();
|
||||
});
|
||||
|
||||
test('POST /workflows/:id/activate should fail due to missing API Key', async () => {
|
||||
|
@ -679,8 +681,8 @@ test('POST /workflows/:id/activate should set workflow as active', async () => {
|
|||
// check whether the workflow is on the database
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow,
|
||||
userId: member.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
relations: ['workflow'],
|
||||
});
|
||||
|
@ -724,17 +726,17 @@ test('POST /workflows/:id/activate should set non-owned workflow as active when
|
|||
// check whether the workflow is on the database
|
||||
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: owner,
|
||||
workflow,
|
||||
userId: owner.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(sharedOwnerWorkflow).toBeUndefined();
|
||||
expect(sharedOwnerWorkflow).toBeNull();
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow,
|
||||
userId: member.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
relations: ['workflow'],
|
||||
});
|
||||
|
@ -824,8 +826,8 @@ test('POST /workflows/:id/deactivate should deactivate workflow', async () => {
|
|||
// get the workflow after it was deactivated
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow,
|
||||
userId: member.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
relations: ['workflow'],
|
||||
});
|
||||
|
@ -869,17 +871,17 @@ test('POST /workflows/:id/deactivate should deactivate non-owned workflow when o
|
|||
// check whether the workflow is deactivated in the database
|
||||
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: owner,
|
||||
workflow,
|
||||
userId: owner.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(sharedOwnerWorkflow).toBeUndefined();
|
||||
expect(sharedOwnerWorkflow).toBeNull();
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow,
|
||||
userId: member.id,
|
||||
workflowId: workflow.id,
|
||||
},
|
||||
relations: ['workflow'],
|
||||
});
|
||||
|
@ -990,8 +992,8 @@ test('POST /workflows should create workflow', async () => {
|
|||
// check if created workflow in DB
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow: response.body,
|
||||
userId: member.id,
|
||||
workflowId: response.body.id,
|
||||
},
|
||||
relations: ['workflow', 'role'],
|
||||
});
|
||||
|
@ -1170,8 +1172,8 @@ test('PUT /workflows/:id should update workflow', async () => {
|
|||
// check updated workflow in DB
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow: response.body,
|
||||
userId: member.id,
|
||||
workflowId: response.body.id,
|
||||
},
|
||||
relations: ['workflow'],
|
||||
});
|
||||
|
@ -1247,17 +1249,17 @@ test('PUT /workflows/:id should update non-owned workflow if owner', async () =>
|
|||
// check updated workflow in DB
|
||||
const sharedOwnerWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: owner,
|
||||
workflow: response.body,
|
||||
userId: owner.id,
|
||||
workflowId: response.body.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(sharedOwnerWorkflow).toBeUndefined();
|
||||
expect(sharedOwnerWorkflow).toBeNull();
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
where: {
|
||||
user: member,
|
||||
workflow: response.body,
|
||||
userId: member.id,
|
||||
workflowId: response.body.id,
|
||||
},
|
||||
relations: ['workflow', 'role'],
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import superagent = require('superagent');
|
||||
import { ObjectLiteral } from 'typeorm';
|
||||
import type { ObjectLiteral } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Make `SuperTest<T>` string-indexable.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { UserSettings } from 'n8n-core';
|
||||
import { Connection, ConnectionOptions, createConnection, getConnection } from 'typeorm';
|
||||
import { DataSource as Connection, DataSourceOptions as ConnectionOptions } from 'typeorm';
|
||||
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
|
@ -50,7 +50,7 @@ export async function init() {
|
|||
// no bootstrap connection required
|
||||
const testDbName = `n8n_test_sqlite_${randomString(6, 10)}_${Date.now()}`;
|
||||
await Db.init(getSqliteOptions({ name: testDbName }));
|
||||
await getConnection(testDbName).runMigrations({ transaction: 'none' });
|
||||
await Db.getConnection().runMigrations({ transaction: 'none' });
|
||||
|
||||
return { testDbName };
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export async function init() {
|
|||
const pgOptions = getBootstrapDBOptions('postgres');
|
||||
|
||||
try {
|
||||
bootstrapPostgres = await createConnection(pgOptions);
|
||||
bootstrapPostgres = await new Connection(pgOptions).initialize();
|
||||
} catch (error) {
|
||||
const pgConfig = getPostgresSchemaSection();
|
||||
|
||||
|
@ -82,15 +82,15 @@ export async function init() {
|
|||
|
||||
const testDbName = `postgres_${randomString(6, 10)}_${Date.now()}_n8n_test`;
|
||||
await bootstrapPostgres.query(`CREATE DATABASE ${testDbName}`);
|
||||
await bootstrapPostgres.close();
|
||||
await bootstrapPostgres.destroy();
|
||||
|
||||
const dbOptions = getDBOptions('postgres', testDbName);
|
||||
|
||||
if (dbOptions.schema !== 'public') {
|
||||
const { schema, migrations, ...options } = dbOptions;
|
||||
const connection = await createConnection(options);
|
||||
const connection = await new Connection(options).initialize();
|
||||
await connection.query(`CREATE SCHEMA IF NOT EXISTS "${schema}"`);
|
||||
await connection.close();
|
||||
await connection.destroy();
|
||||
}
|
||||
|
||||
await Db.init(dbOptions);
|
||||
|
@ -99,11 +99,11 @@ export async function init() {
|
|||
}
|
||||
|
||||
if (dbType === 'mysqldb') {
|
||||
const bootstrapMysql = await createConnection(getBootstrapDBOptions('mysql'));
|
||||
const bootstrapMysql = await new Connection(getBootstrapDBOptions('mysql')).initialize();
|
||||
|
||||
const testDbName = `mysql_${randomString(6, 10)}_${Date.now()}_n8n_test`;
|
||||
await bootstrapMysql.query(`CREATE DATABASE ${testDbName}`);
|
||||
await bootstrapMysql.close();
|
||||
await bootstrapMysql.destroy();
|
||||
|
||||
await Db.init(getDBOptions('mysql', testDbName));
|
||||
|
||||
|
@ -116,8 +116,8 @@ export async function init() {
|
|||
/**
|
||||
* Drop test DB, closing bootstrap connection if existing.
|
||||
*/
|
||||
export async function terminate(testDbName: string) {
|
||||
await getConnection(testDbName).close();
|
||||
export async function terminate() {
|
||||
await Db.getConnection().destroy();
|
||||
}
|
||||
|
||||
async function truncateMappingTables(
|
||||
|
@ -171,9 +171,9 @@ async function truncateMappingTables(
|
|||
* @param collections Array of entity names whose tables to truncate.
|
||||
* @param testDbName Name of the test DB to truncate tables in.
|
||||
*/
|
||||
export async function truncate(collections: Array<CollectionName>, testDbName: string) {
|
||||
export async function truncate(collections: Array<CollectionName>) {
|
||||
const dbType = config.getEnv('database.type');
|
||||
const testDb = getConnection(testDbName);
|
||||
const testDb = Db.getConnection();
|
||||
|
||||
if (dbType === 'sqlite') {
|
||||
await testDb.query('PRAGMA foreign_keys=OFF');
|
||||
|
@ -287,12 +287,12 @@ export async function saveCredential(
|
|||
}
|
||||
|
||||
export async function shareCredentialWithUsers(credential: CredentialsEntity, users: User[]) {
|
||||
const role = await Db.collections.Role.findOne({ scope: 'credential', name: 'user' });
|
||||
const role = await Db.collections.Role.findOneBy({ scope: 'credential', name: 'user' });
|
||||
const newSharedCredentials = users.map((user) =>
|
||||
Db.collections.SharedCredentials.create({
|
||||
user,
|
||||
credentials: credential,
|
||||
role,
|
||||
userId: user.id,
|
||||
credentialsId: credential.id,
|
||||
roleId: role?.id,
|
||||
}),
|
||||
);
|
||||
return Db.collections.SharedCredentials.save(newSharedCredentials);
|
||||
|
@ -333,7 +333,7 @@ export function createUserShell(globalRole: Role): Promise<User> {
|
|||
throw new Error(`Invalid role received: ${JSON.stringify(globalRole)}`);
|
||||
}
|
||||
|
||||
const shell: Partial<User> = { globalRole };
|
||||
const shell: Partial<User> = { globalRoleId: globalRole.id };
|
||||
|
||||
if (globalRole.name !== 'owner') {
|
||||
shell.email = randomEmail();
|
||||
|
@ -405,35 +405,35 @@ export function addApiKey(user: User): Promise<User> {
|
|||
// ----------------------------------
|
||||
|
||||
export function getGlobalOwnerRole() {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'global',
|
||||
});
|
||||
}
|
||||
|
||||
export function getGlobalMemberRole() {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'member',
|
||||
scope: 'global',
|
||||
});
|
||||
}
|
||||
|
||||
export function getWorkflowOwnerRole() {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'workflow',
|
||||
});
|
||||
}
|
||||
|
||||
export function getWorkflowEditorRole() {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'editor',
|
||||
scope: 'workflow',
|
||||
});
|
||||
}
|
||||
|
||||
export function getCredentialOwnerRole() {
|
||||
return Db.collections.Role.findOneOrFail({
|
||||
return Db.collections.Role.findOneByOrFail({
|
||||
name: 'owner',
|
||||
scope: 'credential',
|
||||
});
|
||||
|
@ -641,10 +641,8 @@ export async function createWorkflowWithTrigger(
|
|||
// ----------------------------------
|
||||
|
||||
export async function getWorkflowSharing(workflow: WorkflowEntity) {
|
||||
return Db.collections.SharedWorkflow.find({
|
||||
where: {
|
||||
workflow,
|
||||
},
|
||||
return Db.collections.SharedWorkflow.findBy({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -646,7 +646,7 @@ export function getAuthToken(response: request.Response, authCookieName = AUTH_C
|
|||
// ----------------------------------
|
||||
|
||||
export async function isInstanceOwnerSetUp() {
|
||||
const { value } = await Db.collections.Settings.findOneOrFail({
|
||||
const { value } = await Db.collections.Settings.findOneByOrFail({
|
||||
key: 'userManagement.isInstanceOwnerSetUp',
|
||||
});
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import { NodeMailer } from '@/UserManagement/email/NodeMailer';
|
|||
jest.mock('@/UserManagement/email/NodeMailer');
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalMemberRole: Role;
|
||||
let globalOwnerRole: Role;
|
||||
let workflowOwnerRole: Role;
|
||||
|
@ -34,8 +33,7 @@ let authAgent: AuthAgent;
|
|||
|
||||
beforeAll(async () => {
|
||||
app = await utils.initTestServer({ endpointGroups: ['users'], applyAuth: true });
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
const [
|
||||
fetchedGlobalOwnerRole,
|
||||
|
@ -56,10 +54,7 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(
|
||||
['User', 'SharedCredentials', 'SharedWorkflow', 'Workflow', 'Credentials'],
|
||||
testDbName,
|
||||
);
|
||||
await testDb.truncate(['User', 'SharedCredentials', 'SharedWorkflow', 'Workflow', 'Credentials']);
|
||||
|
||||
jest.mock('@/config');
|
||||
|
||||
|
@ -70,7 +65,7 @@ beforeEach(async () => {
|
|||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('GET /users should return all users', async () => {
|
||||
|
@ -156,28 +151,28 @@ test('DELETE /users/:id should delete the user', async () => {
|
|||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toEqual(SUCCESS_RESPONSE_BODY);
|
||||
|
||||
const user = await Db.collections.User.findOne(userToDelete.id);
|
||||
expect(user).toBeUndefined(); // deleted
|
||||
const user = await Db.collections.User.findOneBy({ id: userToDelete.id });
|
||||
expect(user).toBeNull(); // deleted
|
||||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
|
||||
relations: ['user'],
|
||||
where: { user: userToDelete, role: workflowOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: workflowOwnerRole.id },
|
||||
});
|
||||
expect(sharedWorkflow).toBeUndefined(); // deleted
|
||||
expect(sharedWorkflow).toBeNull(); // deleted
|
||||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOne({
|
||||
relations: ['user'],
|
||||
where: { user: userToDelete, role: credentialOwnerRole },
|
||||
where: { userId: userToDelete.id, roleId: credentialOwnerRole.id },
|
||||
});
|
||||
expect(sharedCredential).toBeUndefined(); // deleted
|
||||
expect(sharedCredential).toBeNull(); // deleted
|
||||
|
||||
const workflow = await Db.collections.Workflow.findOne(savedWorkflow.id);
|
||||
expect(workflow).toBeUndefined(); // deleted
|
||||
const workflow = await Db.collections.Workflow.findOneBy({ id: savedWorkflow.id });
|
||||
expect(workflow).toBeNull(); // deleted
|
||||
|
||||
// TODO: Include active workflow and check whether webhook has been removed
|
||||
|
||||
const credential = await Db.collections.Credentials.findOne(savedCredential.id);
|
||||
expect(credential).toBeUndefined(); // deleted
|
||||
const credential = await Db.collections.Credentials.findOneBy({ id: savedCredential.id });
|
||||
expect(credential).toBeNull(); // deleted
|
||||
});
|
||||
|
||||
test('DELETE /users/:id should fail to delete self', async () => {
|
||||
|
@ -187,7 +182,7 @@ test('DELETE /users/:id should fail to delete self', async () => {
|
|||
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const user = await Db.collections.User.findOne(owner.id);
|
||||
const user = await Db.collections.User.findOneBy({ id: owner.id });
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -202,7 +197,7 @@ test('DELETE /users/:id should fail if user to delete is transferee', async () =
|
|||
|
||||
expect(response.statusCode).toBe(400);
|
||||
|
||||
const user = await Db.collections.User.findOne(idToDelete);
|
||||
const user = await Db.collections.User.findOneBy({ id: idToDelete });
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -226,7 +221,7 @@ test('DELETE /users/:id with transferId should perform transfer', async () => {
|
|||
|
||||
const sharedWorkflow = await Db.collections.SharedWorkflow.findOneOrFail({
|
||||
relations: ['workflow'],
|
||||
where: { user: owner },
|
||||
where: { userId: owner.id },
|
||||
});
|
||||
|
||||
expect(sharedWorkflow.workflow).toBeDefined();
|
||||
|
@ -234,15 +229,15 @@ test('DELETE /users/:id with transferId should perform transfer', async () => {
|
|||
|
||||
const sharedCredential = await Db.collections.SharedCredentials.findOneOrFail({
|
||||
relations: ['credentials'],
|
||||
where: { user: owner },
|
||||
where: { userId: owner.id },
|
||||
});
|
||||
|
||||
expect(sharedCredential.credentials).toBeDefined();
|
||||
expect(sharedCredential.credentials.id).toBe(savedCredential.id);
|
||||
|
||||
const deletedUser = await Db.collections.User.findOne(userToDelete);
|
||||
const deletedUser = await Db.collections.User.findOneBy({ id: userToDelete.id });
|
||||
|
||||
expect(deletedUser).toBeUndefined();
|
||||
expect(deletedUser).toBeNull();
|
||||
});
|
||||
|
||||
test('GET /resolve-signup-token should validate invite token', async () => {
|
||||
|
@ -342,7 +337,7 @@ test('POST /users/:id should fill out a user shell', async () => {
|
|||
const authToken = utils.getAuthToken(response);
|
||||
expect(authToken).toBeDefined();
|
||||
|
||||
const member = await Db.collections.User.findOneOrFail(memberShell.id);
|
||||
const member = await Db.collections.User.findOneByOrFail({ id: memberShell.id });
|
||||
expect(member.firstName).toBe(memberData.firstName);
|
||||
expect(member.lastName).toBe(memberData.lastName);
|
||||
expect(member.password).not.toBe(memberData.password);
|
||||
|
@ -487,7 +482,7 @@ test('POST /users should email invites and create user shells but ignore existin
|
|||
expect(error).toBe('Email could not be sent');
|
||||
}
|
||||
|
||||
const storedUser = await Db.collections.User.findOneOrFail(id);
|
||||
const storedUser = await Db.collections.User.findOneByOrFail({ id });
|
||||
const { firstName, lastName, personalizationAnswers, password, resetPasswordToken } =
|
||||
storedUser;
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import { randomCredentialPayload } from './shared/random';
|
|||
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
let globalMemberRole: Role;
|
||||
let credentialOwnerRole: Role;
|
||||
|
@ -29,8 +28,7 @@ beforeAll(async () => {
|
|||
endpointGroups: ['workflows'],
|
||||
applyAuth: true,
|
||||
});
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
globalMemberRole = await testDb.getGlobalMemberRole();
|
||||
|
@ -53,11 +51,11 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User', 'Workflow', 'SharedWorkflow'], testDbName);
|
||||
await testDb.truncate(['User', 'Workflow', 'SharedWorkflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('Router should switch dynamically', async () => {
|
||||
|
|
|
@ -9,7 +9,6 @@ import type { IPinData } from 'n8n-workflow';
|
|||
import { makeWorkflow, MOCK_PINDATA } from './shared/utils';
|
||||
|
||||
let app: express.Application;
|
||||
let testDbName = '';
|
||||
let globalOwnerRole: Role;
|
||||
|
||||
// mock whether sharing is enabled or not
|
||||
|
@ -20,8 +19,7 @@ beforeAll(async () => {
|
|||
endpointGroups: ['workflows'],
|
||||
applyAuth: true,
|
||||
});
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
globalOwnerRole = await testDb.getGlobalOwnerRole();
|
||||
|
||||
|
@ -30,11 +28,11 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['User', 'Workflow', 'SharedWorkflow'], testDbName);
|
||||
await testDb.truncate(['User', 'Workflow', 'SharedWorkflow']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
test('POST /workflows should store pin data for node in workflow', async () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'tsconfig-paths/register';
|
||||
import { createConnection } from 'typeorm';
|
||||
import { DataSource as Connection } from 'typeorm';
|
||||
import config from '@/config';
|
||||
import { getBootstrapDBOptions } from './integration/shared/testDb';
|
||||
|
||||
|
@ -7,7 +7,8 @@ export default async () => {
|
|||
const dbType = config.getEnv('database.type').replace(/db$/, '');
|
||||
if (dbType !== 'postgres' && dbType !== 'mysql') return;
|
||||
|
||||
const connection = await createConnection(getBootstrapDBOptions(dbType));
|
||||
const connection = new Connection(getBootstrapDBOptions(dbType));
|
||||
await connection.initialize();
|
||||
|
||||
const query =
|
||||
dbType === 'postgres' ? 'SELECT datname as "Database" FROM pg_database' : 'SHOW DATABASES';
|
||||
|
@ -20,5 +21,5 @@ export default async () => {
|
|||
|
||||
const promises = databases.map((dbName) => connection.query(`DROP DATABASE ${dbName};`));
|
||||
await Promise.all(promises);
|
||||
await connection.close();
|
||||
await connection.destroy();
|
||||
};
|
||||
|
|
|
@ -25,15 +25,13 @@ import type { SaveCredentialFunction } from '../integration/shared/types';
|
|||
import { User } from '@/databases/entities/User';
|
||||
import { SharedWorkflow } from '@/databases/entities/SharedWorkflow';
|
||||
|
||||
let testDbName = '';
|
||||
let mockNodeTypes: INodeTypes;
|
||||
let credentialOwnerRole: Role;
|
||||
let workflowOwnerRole: Role;
|
||||
let saveCredential: SaveCredentialFunction;
|
||||
|
||||
beforeAll(async () => {
|
||||
const initResult = await testDb.init();
|
||||
testDbName = initResult.testDbName;
|
||||
await testDb.init();
|
||||
|
||||
mockNodeTypes = MockNodeTypes({
|
||||
loaded: {
|
||||
|
@ -51,12 +49,12 @@ beforeAll(async () => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testDb.truncate(['SharedWorkflow', 'SharedCredentials'], testDbName);
|
||||
await testDb.truncate(['User', 'Workflow', 'Credentials'], testDbName);
|
||||
await testDb.truncate(['SharedWorkflow', 'SharedCredentials']);
|
||||
await testDb.truncate(['User', 'Workflow', 'Credentials']);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testDb.terminate(testDbName);
|
||||
await testDb.terminate();
|
||||
});
|
||||
|
||||
describe('PermissionChecker.check()', () => {
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('Telemetry', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
spyTrack.mockClear();
|
||||
telemetry = new Telemetry(instanceId, n8nVersion);
|
||||
telemetry = new Telemetry(instanceId);
|
||||
(telemetry as any).rudderStack = {
|
||||
flush: () => {},
|
||||
identify: () => {},
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { INode, IWorkflowCredentials } from 'n8n-workflow';
|
|||
import * as Db from '@/Db';
|
||||
import { WorkflowCredentials } from '@/WorkflowCredentials';
|
||||
|
||||
// Define a function used to mock the findOne function
|
||||
// Define a function used to mock the findOneBy function
|
||||
async function mockFind({
|
||||
id,
|
||||
type,
|
||||
|
@ -33,7 +33,7 @@ jest.mock('@/Db', () => {
|
|||
return {
|
||||
collections: {
|
||||
Credentials: {
|
||||
findOne: jest.fn(mockFind),
|
||||
findOneBy: jest.fn(mockFind),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -54,7 +54,7 @@ describe('WorkflowCredentials', () => {
|
|||
`Credentials with name "${credentials.name}" for type "test" miss an ID.`,
|
||||
);
|
||||
expect(WorkflowCredentials([noIdNode])).rejects.toEqual(expectedError);
|
||||
expect(mocked(Db.collections.Credentials.findOne)).toHaveBeenCalledTimes(0);
|
||||
expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('Should return an error if credentials cannot be found in the DB', () => {
|
||||
|
@ -63,7 +63,7 @@ describe('WorkflowCredentials', () => {
|
|||
`Could not find credentials for type "test" with ID "${credentials.id}".`,
|
||||
);
|
||||
expect(WorkflowCredentials([notFoundNode])).rejects.toEqual(expectedError);
|
||||
expect(mocked(Db.collections.Credentials.findOne)).toHaveBeenCalledTimes(1);
|
||||
expect(mocked(Db.collections.Credentials.findOneBy)).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('Should ignore duplicates', async () => {
|
||||
|
|
|
@ -184,7 +184,7 @@ importers:
|
|||
lodash.uniqby: ^4.7.0
|
||||
lodash.unset: ^4.5.2
|
||||
luxon: ^3.1.0
|
||||
mysql2: ~2.3.0
|
||||
mysql2: ~2.3.3
|
||||
n8n-core: ~0.151.0
|
||||
n8n-editor-ui: ~0.177.0
|
||||
n8n-nodes-base: ~0.209.0
|
||||
|
@ -199,7 +199,7 @@ importers:
|
|||
passport: ^0.6.0
|
||||
passport-cookie: ^1.0.9
|
||||
passport-jwt: ^4.0.0
|
||||
pg: ^8.3.0
|
||||
pg: ^8.8.0
|
||||
picocolors: ^1.0.0
|
||||
posthog-node: ^2.2.2
|
||||
prom-client: ^13.1.0
|
||||
|
@ -209,7 +209,7 @@ importers:
|
|||
semver: ^7.3.8
|
||||
shelljs: ^0.8.5
|
||||
source-map-support: ^0.5.21
|
||||
sqlite3: ^5.1.2
|
||||
sqlite3: ^5.1.4
|
||||
sse-channel: ^4.0.0
|
||||
supertest: ^6.2.2
|
||||
swagger-ui-express: ^4.3.0
|
||||
|
@ -218,7 +218,7 @@ importers:
|
|||
tsc-alias: ^1.7.0
|
||||
tsconfig-paths: ^3.14.1
|
||||
tslib: 1.14.1
|
||||
typeorm: 0.2.45
|
||||
typeorm: 0.3.11
|
||||
uuid: ^8.3.2
|
||||
validator: 13.7.0
|
||||
winston: ^3.3.3
|
||||
|
@ -299,12 +299,12 @@ importers:
|
|||
semver: 7.3.8
|
||||
shelljs: 0.8.5
|
||||
source-map-support: 0.5.21
|
||||
sqlite3: 5.1.2
|
||||
sqlite3: 5.1.4
|
||||
sse-channel: 4.0.0
|
||||
swagger-ui-express: 4.5.0_express@4.18.2
|
||||
syslog-client: 1.1.1
|
||||
tslib: 1.14.1
|
||||
typeorm: 0.2.45_b2izk5tn6tm5xb65gvog337urq
|
||||
typeorm: 0.3.11_a77gzgdqnod3rkvxniiwirlqsi
|
||||
uuid: 8.3.2
|
||||
validator: 13.7.0
|
||||
winston: 3.8.2
|
||||
|
@ -3481,6 +3481,7 @@ packages:
|
|||
/@npmcli/move-file/1.1.2:
|
||||
resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: This functionality has been moved to @npmcli/fs
|
||||
dependencies:
|
||||
mkdirp: 1.0.4
|
||||
rimraf: 3.0.2
|
||||
|
@ -6407,10 +6408,6 @@ packages:
|
|||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/zen-observable/0.8.3:
|
||||
resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==}
|
||||
dev: false
|
||||
|
||||
/@typescript-eslint/eslint-plugin/5.45.0_psz44bhp76u27vmulntnlx26h4:
|
||||
resolution: {integrity: sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
@ -7378,7 +7375,6 @@ packages:
|
|||
|
||||
/arg/4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
dev: true
|
||||
|
||||
/argparse/1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
|
@ -9707,7 +9703,6 @@ packages:
|
|||
|
||||
/create-require/1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
dev: true
|
||||
|
||||
/crelt/1.0.5:
|
||||
resolution: {integrity: sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==}
|
||||
|
@ -9998,7 +9993,6 @@ packages:
|
|||
/date-fns/2.29.3:
|
||||
resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==}
|
||||
engines: {node: '>=0.11'}
|
||||
dev: true
|
||||
|
||||
/date-now/0.1.4:
|
||||
resolution: {integrity: sha512-AsElvov3LoNB7tf5k37H2jYSB+ZZPMT5sG2QjJCcdlV5chIv6htBUBUui2IKRjgtKAKtCBN7Zbwa+MtwLjSeNw==}
|
||||
|
@ -10307,7 +10301,6 @@ packages:
|
|||
/diff/4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
dev: true
|
||||
|
||||
/diffie-hellman/5.0.3:
|
||||
resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
|
||||
|
@ -10460,7 +10453,6 @@ packages:
|
|||
/dotenv/16.0.3:
|
||||
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/dotenv/8.6.0:
|
||||
resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
|
||||
|
@ -19609,8 +19601,8 @@ packages:
|
|||
resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==}
|
||||
dev: false
|
||||
|
||||
/sqlite3/5.1.2:
|
||||
resolution: {integrity: sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==}
|
||||
/sqlite3/5.1.4:
|
||||
resolution: {integrity: sha512-i0UlWAzPlzX3B5XP2cYuhWQJsTtlMD6obOa1PgeEQ4DHEXUuyJkgv50I3isqZAP5oFc2T8OFvakmDh2W6I+YpA==}
|
||||
requiresBuild: true
|
||||
peerDependenciesMeta:
|
||||
node-gyp:
|
||||
|
@ -20732,7 +20724,6 @@ packages:
|
|||
source-map-support: 0.5.21
|
||||
typescript: 4.8.4
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/ts-pnp/1.2.0_typescript@4.8.4:
|
||||
resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
|
||||
|
@ -20935,26 +20926,31 @@ packages:
|
|||
/typedarray/0.0.6:
|
||||
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
|
||||
|
||||
/typeorm/0.2.45_b2izk5tn6tm5xb65gvog337urq:
|
||||
resolution: {integrity: sha512-c0rCO8VMJ3ER7JQ73xfk0zDnVv0WDjpsP6Q1m6CVKul7DB9iVdWLRjPzc8v2eaeBuomsbZ2+gTaYr8k1gm3bYA==}
|
||||
/typeorm/0.3.11_a77gzgdqnod3rkvxniiwirlqsi:
|
||||
resolution: {integrity: sha512-pzdOyWbVuz/z8Ww6gqvBW4nylsM0KLdUCDExr2gR20/x1khGSVxQkjNV/3YqliG90jrWzrknYbYscpk8yxFJVg==}
|
||||
engines: {node: '>= 12.9.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@sap/hana-client': ^2.11.14
|
||||
better-sqlite3: ^7.1.2
|
||||
'@google-cloud/spanner': ^5.18.0
|
||||
'@sap/hana-client': ^2.12.25
|
||||
better-sqlite3: ^7.1.2 || ^8.0.0
|
||||
hdb-pool: ^0.1.6
|
||||
ioredis: ^4.28.3
|
||||
ioredis: ^5.0.4
|
||||
mongodb: ^3.6.0
|
||||
mssql: ^6.3.1
|
||||
mssql: ^7.3.0
|
||||
mysql2: ^2.2.5
|
||||
oracledb: ^5.1.0
|
||||
pg: ^8.5.1
|
||||
pg-native: ^3.0.0
|
||||
pg-query-stream: ^4.0.0
|
||||
redis: ^3.1.1
|
||||
redis: ^3.1.1 || ^4.0.0
|
||||
sql.js: ^1.4.0
|
||||
sqlite3: ^5.0.2
|
||||
sqlite3: ^5.0.3
|
||||
ts-node: ^10.7.0
|
||||
typeorm-aurora-data-api-driver: ^2.0.0
|
||||
peerDependenciesMeta:
|
||||
'@google-cloud/spanner':
|
||||
optional: true
|
||||
'@sap/hana-client':
|
||||
optional: true
|
||||
better-sqlite3:
|
||||
|
@ -20983,6 +20979,8 @@ packages:
|
|||
optional: true
|
||||
sqlite3:
|
||||
optional: true
|
||||
ts-node:
|
||||
optional: true
|
||||
typeorm-aurora-data-api-driver:
|
||||
optional: true
|
||||
dependencies:
|
||||
|
@ -20991,8 +20989,9 @@ packages:
|
|||
buffer: 6.0.3
|
||||
chalk: 4.1.2
|
||||
cli-highlight: 2.1.11
|
||||
date-fns: 2.29.3
|
||||
debug: 4.3.4
|
||||
dotenv: 8.6.0
|
||||
dotenv: 16.0.3
|
||||
glob: 7.2.3
|
||||
ioredis: 5.2.4
|
||||
js-yaml: 4.1.0
|
||||
|
@ -21001,12 +21000,12 @@ packages:
|
|||
pg: 8.8.0
|
||||
reflect-metadata: 0.1.13
|
||||
sha.js: 2.4.11
|
||||
sqlite3: 5.1.2
|
||||
sqlite3: 5.1.4
|
||||
ts-node: 9.1.1_typescript@4.8.4
|
||||
tslib: 2.4.0
|
||||
uuid: 8.3.2
|
||||
xml2js: 0.4.23
|
||||
yargs: 17.6.0
|
||||
zen-observable-ts: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
@ -22715,7 +22714,6 @@ packages:
|
|||
/yn/3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/yocto-queue/0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
|
@ -22747,17 +22745,6 @@ packages:
|
|||
commander: 2.20.3
|
||||
dev: true
|
||||
|
||||
/zen-observable-ts/1.1.0:
|
||||
resolution: {integrity: sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==}
|
||||
dependencies:
|
||||
'@types/zen-observable': 0.8.3
|
||||
zen-observable: 0.8.15
|
||||
dev: false
|
||||
|
||||
/zen-observable/0.8.15:
|
||||
resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==}
|
||||
dev: false
|
||||
|
||||
/zwitch/1.0.5:
|
||||
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
|
||||
dev: true
|
||||
|
|
Loading…
Reference in a new issue