Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PagerDuty node: add support for additional details for the incident #3140

Merged
merged 8 commits into from
Apr 15, 2022
59,681 changes: 877 additions & 58,804 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions packages/cli/commands/export/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ export class ExportCredentialsCommand extends Command {

if (flags.decrypted) {
const encryptionKey = await UserSettings.getEncryptionKey();
if (encryptionKey === undefined) {
throw new Error('No encryption key got found to decrypt the credentials!');
}

for (let i = 0; i < credentials.length; i++) {
const { name, type, nodesAccess, data } = credentials[i];
Expand Down
3 changes: 0 additions & 3 deletions packages/cli/commands/import/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ export class ImportCredentialsCommand extends Command {
await UserSettings.prepareUserSettings();

const encryptionKey = await UserSettings.getEncryptionKey();
if (encryptionKey === undefined) {
throw new Error('No encryption key found to encrypt the credentials!');
}

if (flags.separate) {
const files = await glob(
Expand Down
10 changes: 1 addition & 9 deletions packages/cli/commands/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
} from '../src';

import { getLogger } from '../src/Logger';
import { RESPONSE_ERROR_MESSAGES } from '../src/constants';

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
const open = require('open');
Expand Down Expand Up @@ -173,9 +172,6 @@ export class Start extends Command {
// If we don't have a JWT secret set, generate
// one based and save to config.
const encryptionKey = await UserSettings.getEncryptionKey();
if (!encryptionKey) {
throw new Error('Fatal error setting up user management: no encryption key set.');
}

// For a key off every other letter from encryption key
// CAREFUL: do not change this or it breaks all existing tokens.
Expand Down Expand Up @@ -210,11 +206,7 @@ export class Start extends Command {
// Wait till the database is ready
await startDbInitPromise;

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
throw new Error(RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY);
}
await UserSettings.getEncryptionKey();

// Load settings from database and set them to config.
const databaseSettings = await Db.collections.Settings.find({ loadOnStartup: true });
Expand Down
52 changes: 20 additions & 32 deletions packages/cli/src/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1703,13 +1703,11 @@ class App {
);
}

const encryptionKey = await UserSettings.getEncryptionKey();
if (!encryptionKey) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
500,
);
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(error.message, undefined, 500);
}

const mode: WorkflowExecuteMode = 'internal';
Expand Down Expand Up @@ -1842,15 +1840,11 @@ class App {
return ResponseHelper.sendErrorResponse(res, errorResponse);
}

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
const errorResponse = new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
503,
);
return ResponseHelper.sendErrorResponse(res, errorResponse);
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(error.message, undefined, 500);
}

const mode: WorkflowExecuteMode = 'internal';
Expand Down Expand Up @@ -1962,13 +1956,11 @@ class App {
);
}

const encryptionKey = await UserSettings.getEncryptionKey();
if (!encryptionKey) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
500,
);
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(error.message, undefined, 500);
}

const mode: WorkflowExecuteMode = 'internal';
Expand Down Expand Up @@ -2103,15 +2095,11 @@ class App {
return ResponseHelper.sendErrorResponse(res, errorResponse);
}

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
const errorResponse = new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
503,
);
return ResponseHelper.sendErrorResponse(res, errorResponse);
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(error.message, undefined, 500);
}

const mode: WorkflowExecuteMode = 'internal';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from './Interfaces';
import { NodeMailer } from './NodeMailer';

// TODO: make function fully async (remove sync functions)
async function getTemplate(configKeyName: string, defaultFilename: string) {
const templateOverride = (await GenericHelpers.getConfigValue(
`userManagement.emails.templates.${configKeyName}`,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/UserManagement/routes/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export function usersNamespace(this: N8nApp): void {
400,
);
}
createUsers[invite.email] = null;
createUsers[invite.email.toLowerCase()] = null;
});

const role = await Db.collections.Role.findOne({ scope: 'global', name: 'member' });
Expand Down
4 changes: 1 addition & 3 deletions packages/cli/src/WorkflowExecuteAdditionalData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {
getWorkflowOwner,
} from './UserManagement/UserManagementHelper';
import { whereClause } from './WorkflowHelpers';
import { RESPONSE_ERROR_MESSAGES } from './constants';

const ERROR_TRIGGER_TYPE = config.getEnv('nodes.errorTriggerType');

Expand Down Expand Up @@ -1030,9 +1031,6 @@ export async function getBase(
const webhookTestBaseUrl = urlBaseWebhook + config.getEnv('endpoints.webhookTest');

const encryptionKey = await UserSettings.getEncryptionKey();
if (encryptionKey === undefined) {
throw new Error('No encryption key got found to decrypt the credentials!');
}

return {
credentialsHelper: new CredentialsHelper(encryptionKey),
Expand Down
37 changes: 21 additions & 16 deletions packages/cli/src/api/credentials.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,15 @@ credentialsController.post(
ResponseHelper.send(async (req: CredentialRequest.Test): Promise<INodeCredentialTestResult> => {
const { credentials, nodeToTestWith } = req.body;

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
return {
status: 'Error',
message: RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
};
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
500,
);
}

const helper = new CredentialsHelper(encryptionKey);
Expand Down Expand Up @@ -149,9 +151,10 @@ credentialsController.post(
nodeAccess.date = new Date();
}

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
Expand Down Expand Up @@ -285,9 +288,10 @@ credentialsController.patch(
}
}

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
Expand Down Expand Up @@ -393,9 +397,10 @@ credentialsController.get(

const { data, id, ...rest } = credential;

const encryptionKey = await UserSettings.getEncryptionKey();

if (!encryptionKey) {
let encryptionKey: string;
try {
encryptionKey = await UserSettings.getEncryptionKey();
} catch (error) {
throw new ResponseHelper.ResponseError(
RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
undefined,
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/naming-convention */

import { RESPONSE_ERROR_MESSAGES as CORE_RESPONSE_ERROR_MESSAGES } from 'n8n-core';

export const RESPONSE_ERROR_MESSAGES = {
NO_CREDENTIAL: 'Credential not found',
NO_ENCRYPTION_KEY: 'Encryption key missing to decrypt credentials',
NO_ENCRYPTION_KEY: CORE_RESPONSE_ERROR_MESSAGES.NO_ENCRYPTION_KEY,
};

export const AUTH_COOKIE_NAME = 'n8n-auth';
13 changes: 10 additions & 3 deletions packages/cli/src/databases/entities/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
BeforeInsert,
} from 'typeorm';
import { IsEmail, IsString, Length } from 'class-validator';
import * as config from '../../../config';
Expand All @@ -20,7 +21,7 @@ import { Role } from './Role';
import { SharedWorkflow } from './SharedWorkflow';
import { SharedCredentials } from './SharedCredentials';
import { NoXss } from '../utils/customValidators';
import { answersFormatter } from '../utils/transformers';
import { answersFormatter, lowerCaser } from '../utils/transformers';

export const MIN_PASSWORD_LENGTH = 8;

Expand Down Expand Up @@ -62,7 +63,11 @@ export class User {
@PrimaryGeneratedColumn('uuid')
id: string;

@Column({ length: 254, nullable: true })
@Column({
length: 254,
nullable: true,
transformer: lowerCaser,
})
@Index({ unique: true })
@IsEmail()
email: string;
Expand Down Expand Up @@ -119,8 +124,10 @@ export class User {
})
updatedAt: Date;

@BeforeInsert()
@BeforeUpdate()
setUpdateDate(): void {
preUpsertHook(): void {
this.email = this.email?.toLowerCase();
this.updatedAt = new Date();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config = require('../../../../config');

export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
name = 'LowerCaseUserEmail1648740597343';

public async up(queryRunner: QueryRunner): Promise<void> {
const tablePrefix = config.get('database.tablePrefix');

await queryRunner.query(`
UPDATE ${tablePrefix}user
SET email = LOWER(email);
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {}
}
2 changes: 2 additions & 0 deletions packages/cli/src/databases/mysqldb/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AddWaitColumnId1626183952959 } from './1626183952959-AddWaitColumn';
import { UpdateWorkflowCredentials1630451444017 } from './1630451444017-UpdateWorkflowCredentials';
import { AddExecutionEntityIndexes1644424784709 } from './1644424784709-AddExecutionEntityIndexes';
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';

export const mysqlMigrations = [
InitialMigration1588157391238,
Expand All @@ -28,4 +29,5 @@ export const mysqlMigrations = [
UpdateWorkflowCredentials1630451444017,
AddExecutionEntityIndexes1644424784709,
CreateUserManagement1646992772331,
LowerCaseUserEmail1648740597343,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config = require('../../../../config');

export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
name = 'LowerCaseUserEmail1648740597343';

public async up(queryRunner: QueryRunner): Promise<void> {
let tablePrefix = config.get('database.tablePrefix');
const schema = config.get('database.postgresdb.schema');
if (schema) {
tablePrefix = schema + '.' + tablePrefix;
}

await queryRunner.query(`
UPDATE ${tablePrefix}user
SET email = LOWER(email);
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {}
}
2 changes: 2 additions & 0 deletions packages/cli/src/databases/postgresdb/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { UpdateWorkflowCredentials1630419189837 } from './1630419189837-UpdateWo
import { AddExecutionEntityIndexes1644422880309 } from './1644422880309-AddExecutionEntityIndexes';
import { IncreaseTypeVarcharLimit1646834195327 } from './1646834195327-IncreaseTypeVarcharLimit';
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';

export const postgresMigrations = [
InitialMigration1587669153312,
Expand All @@ -24,4 +25,5 @@ export const postgresMigrations = [
AddExecutionEntityIndexes1644422880309,
IncreaseTypeVarcharLimit1646834195327,
CreateUserManagement1646992772331,
LowerCaseUserEmail1648740597343,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import config = require('../../../../config');
import { logMigrationEnd, logMigrationStart } from '../../utils/migrationHelpers';

export class LowerCaseUserEmail1648740597343 implements MigrationInterface {
name = 'LowerCaseUserEmail1648740597343';

public async up(queryRunner: QueryRunner): Promise<void> {
logMigrationStart(this.name);

const tablePrefix = config.get('database.tablePrefix');

await queryRunner.query(`
UPDATE "${tablePrefix}user"
SET email = LOWER(email);
`);

logMigrationEnd(this.name);
}

public async down(queryRunner: QueryRunner): Promise<void> {}
}
2 changes: 2 additions & 0 deletions packages/cli/src/databases/sqlite/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AddWaitColumn1621707690587 } from './1621707690587-AddWaitColumn';
import { UpdateWorkflowCredentials1630330987096 } from './1630330987096-UpdateWorkflowCredentials';
import { AddExecutionEntityIndexes1644421939510 } from './1644421939510-AddExecutionEntityIndexes';
import { CreateUserManagement1646992772331 } from './1646992772331-CreateUserManagement';
import { LowerCaseUserEmail1648740597343 } from './1648740597343-LowerCaseUserEmail';

const sqliteMigrations = [
InitialMigration1588102412422,
Expand All @@ -24,6 +25,7 @@ const sqliteMigrations = [
UpdateWorkflowCredentials1630330987096,
AddExecutionEntityIndexes1644421939510,
CreateUserManagement1646992772331,
LowerCaseUserEmail1648740597343,
];

export { sqliteMigrations };
Loading