Compare commits
2 Commits
bin-js
...
custom-ais
Author | SHA1 | Date | |
---|---|---|---|
![]() |
74494989d2 | ||
![]() |
e122ad4178 |
@@ -1,28 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['@typescript-eslint'],
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'prettier',
|
|
||||||
],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['**/*.test.ts', '**/test/**/*.ts'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/ban-ts-comment': ['off'],
|
|
||||||
'@typescript-eslint/no-explicit-any': ['off'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/*.ts'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-explicit-any': ['off'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
@@ -6,9 +6,10 @@ import Role from '../../src/models/role';
|
|||||||
import '../../src/config/orm';
|
import '../../src/config/orm';
|
||||||
|
|
||||||
async function fetchAdminRole() {
|
async function fetchAdminRole() {
|
||||||
const role = await Role.query()
|
const role = await Role
|
||||||
|
.query()
|
||||||
.where({
|
.where({
|
||||||
key: 'admin',
|
key: 'admin'
|
||||||
})
|
})
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.first();
|
.first();
|
||||||
@@ -40,7 +41,7 @@ export async function createUser(
|
|||||||
logger.info('No need to seed a user.');
|
logger.info('No need to seed a user.');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.nativeError.code !== UNIQUE_VIOLATION_CODE) {
|
if ((err as any).nativeError.code !== UNIQUE_VIOLATION_CODE) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ export const createDatabase = async (database = appConfig.postgresDatabase) => {
|
|||||||
await client.query(`CREATE DATABASE ${database}`);
|
await client.query(`CREATE DATABASE ${database}`);
|
||||||
logger.info(`Database: ${database} created!`);
|
logger.info(`Database: ${database} created!`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== DUPLICATE_DB_CODE) {
|
if ((err as any).code !== DUPLICATE_DB_CODE) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ export const createDatabaseUser = async (user = appConfig.postgresUsername) => {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== DUPLICATE_OBJECT_CODE) {
|
if ((err as any).code !== DUPLICATE_OBJECT_CODE) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
@@ -1,3 +0,0 @@
|
|||||||
import newChat from './new-chat';
|
|
||||||
|
|
||||||
export default [newChat];
|
|
@@ -1,50 +0,0 @@
|
|||||||
import FormData from 'form-data';
|
|
||||||
import defineAction from '../../../../helpers/define-action';
|
|
||||||
|
|
||||||
export default defineAction({
|
|
||||||
name: 'New chat',
|
|
||||||
key: 'newChat',
|
|
||||||
description: 'Create a new chat session for Helix AI.',
|
|
||||||
arguments: [
|
|
||||||
{
|
|
||||||
label: 'Input',
|
|
||||||
key: 'input',
|
|
||||||
type: 'string' as const,
|
|
||||||
required: true,
|
|
||||||
description: 'Prompt to start the chat with.',
|
|
||||||
variables: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
async run($) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('input', $.step.parameters.input as string);
|
|
||||||
formData.append('mode', 'inference');
|
|
||||||
formData.append('type', 'text');
|
|
||||||
|
|
||||||
const sessionResponse = await $.http.post('/api/v1/sessions', formData, {
|
|
||||||
headers: {
|
|
||||||
...formData.getHeaders(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const sessionId = sessionResponse.data.id;
|
|
||||||
|
|
||||||
let chatGenerated = false;
|
|
||||||
|
|
||||||
while (!chatGenerated) {
|
|
||||||
const response = await $.http.get(`/api/v1/sessions/${sessionId}`);
|
|
||||||
|
|
||||||
const message =
|
|
||||||
response.data.interactions[response.data.interactions.length - 1];
|
|
||||||
|
|
||||||
if (message.creator === 'system' && message.state === 'complete') {
|
|
||||||
$.setActionItem({
|
|
||||||
raw: message,
|
|
||||||
});
|
|
||||||
|
|
||||||
chatGenerated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
@@ -1,6 +0,0 @@
|
|||||||
<svg role="img" viewBox="0 0 47 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M15.9268 3.41382L15.7675 21.2642L15.5102 52.1134V58.1779C15.4898 58.7861 15.631 59.3888 15.9194 59.9247C16.2078 60.4606 16.6331 60.9105 17.1519 61.2285L24.1843 65.296L25.6299 66.1291C27.7314 67.3481 30.1162 67.9938 32.5456 68.0014C34.975 68.009 37.3638 67.3783 39.4729 66.1724C41.5819 64.9666 43.3372 63.2278 44.563 61.1303C45.7888 59.0328 46.442 56.65 46.4574 54.2206L46.7147 23.3837V17.258C46.7207 16.6458 46.564 16.0429 46.2604 15.5112C45.9569 14.9795 45.5175 14.538 44.9873 14.2319L39.7559 11.218L36.5337 9.36804L21.0602 0.436718C20.5374 0.146102 19.9481 -0.00382494 19.3501 0.00160738C18.752 0.0070397 18.1655 0.167645 17.6482 0.467709C17.1308 0.767772 16.7001 1.19701 16.3984 1.71343C16.0967 2.22985 15.9342 2.81576 15.9268 3.41382Z" fill="#16C3E4" fill-opacity="0.8"></path>
|
|
||||||
<g style="mix-blend-mode:hard-light">
|
|
||||||
<path d="M31.3986 35.0108L31.1636 63.0174C31.1434 63.6524 30.9604 64.2716 30.6322 64.8156C30.304 65.3596 29.8415 65.8101 29.2892 66.1241C28.7368 66.4381 28.1131 66.605 27.4777 66.6088C26.8423 66.6126 26.2166 66.4532 25.6605 66.1458L1.80552 52.1981C1.25401 51.8682 0.797643 51.4008 0.481139 50.8416C0.164634 50.2823 -0.00115693 49.6505 6.0768e-06 49.0079L0.23497 21.1867C0.25531 20.5542 0.437144 19.9374 0.763178 19.395C1.08921 18.8526 1.5486 18.4026 2.09766 18.0879C2.64672 17.7731 3.26719 17.604 3.90005 17.5967C4.53292 17.5894 5.15714 17.744 5.71334 18.046L29.5684 31.8082C30.1263 32.1361 30.5887 32.6041 30.9098 33.1659C31.2309 33.7277 31.3994 34.3637 31.3986 35.0108Z" fill="#C43BBB"></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,45 +0,0 @@
|
|||||||
import verifyCredentials from './verify-credentials';
|
|
||||||
import isStillVerified from './is-still-verified';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
key: 'screenName',
|
|
||||||
label: 'Screen Name',
|
|
||||||
type: 'string' as const,
|
|
||||||
required: true,
|
|
||||||
readOnly: false,
|
|
||||||
value: null,
|
|
||||||
placeholder: null,
|
|
||||||
description:
|
|
||||||
'Screen name of your connection to be used on Automatisch UI.',
|
|
||||||
clickToCopy: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'instanceUrl',
|
|
||||||
label: 'Helix instance URL',
|
|
||||||
type: 'string' as const,
|
|
||||||
required: false,
|
|
||||||
readOnly: false,
|
|
||||||
value: 'https://app.tryhelix.ai',
|
|
||||||
placeholder: 'https://app.tryhelix.ai',
|
|
||||||
description:
|
|
||||||
'Your Helix instance URL. Default is https://app.tryhelix.ai.',
|
|
||||||
clickToCopy: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'apiKey',
|
|
||||||
label: 'API Key',
|
|
||||||
type: 'string' as const,
|
|
||||||
required: true,
|
|
||||||
readOnly: false,
|
|
||||||
value: null,
|
|
||||||
placeholder: null,
|
|
||||||
description: 'Helix API Key of your account.',
|
|
||||||
clickToCopy: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
verifyCredentials,
|
|
||||||
isStillVerified,
|
|
||||||
};
|
|
@@ -1,9 +0,0 @@
|
|||||||
import { IGlobalVariable } from '@automatisch/types';
|
|
||||||
import verifyCredentials from './verify-credentials';
|
|
||||||
|
|
||||||
const isStillVerified = async ($: IGlobalVariable) => {
|
|
||||||
await verifyCredentials($);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default isStillVerified;
|
|
@@ -1,11 +0,0 @@
|
|||||||
import { IGlobalVariable } from '@automatisch/types';
|
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
|
||||||
await $.http.get('/api/v1/sessions');
|
|
||||||
|
|
||||||
await $.auth.set({
|
|
||||||
screenName: $.auth.data.screenName,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default verifyCredentials;
|
|
@@ -1,12 +0,0 @@
|
|||||||
import { TBeforeRequest } from '@automatisch/types';
|
|
||||||
|
|
||||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
|
||||||
if ($.auth.data?.apiKey) {
|
|
||||||
const authorizationHeader = `Bearer ${$.auth.data.apiKey}`;
|
|
||||||
requestConfig.headers.Authorization = authorizationHeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default addAuthHeader;
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { TBeforeRequest } from '@automatisch/types';
|
|
||||||
|
|
||||||
const setBaseUrl: TBeforeRequest = ($, requestConfig) => {
|
|
||||||
if ($.auth.data.instanceUrl) {
|
|
||||||
requestConfig.baseURL = $.auth.data.instanceUrl as string;
|
|
||||||
} else if ($.app.apiBaseUrl) {
|
|
||||||
requestConfig.baseURL = $.app.apiBaseUrl as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default setBaseUrl;
|
|
@@ -1,19 +0,0 @@
|
|||||||
import defineApp from '../../helpers/define-app';
|
|
||||||
import setBaseUrl from './common/set-base-url';
|
|
||||||
import addAuthHeader from './common/add-auth-header';
|
|
||||||
import auth from './auth';
|
|
||||||
import actions from './actions';
|
|
||||||
|
|
||||||
export default defineApp({
|
|
||||||
name: 'Helix',
|
|
||||||
key: 'helix',
|
|
||||||
baseUrl: 'https://tryhelix.ai',
|
|
||||||
apiBaseUrl: 'https://app.tryhelix.ai',
|
|
||||||
iconUrl: '{BASE_URL}/apps/helix/assets/favicon.svg',
|
|
||||||
authDocUrl: 'https://automatisch.io/docs/apps/helix/connection',
|
|
||||||
primaryColor: '000000',
|
|
||||||
supportsConnections: true,
|
|
||||||
beforeRequest: [setBaseUrl, addAuthHeader],
|
|
||||||
auth,
|
|
||||||
actions,
|
|
||||||
});
|
|
@@ -1,7 +1,6 @@
|
|||||||
import { URL } from 'node:url';
|
import { URL } from 'node:url';
|
||||||
import * as dotenv from 'dotenv';
|
import * as dotenv from 'dotenv';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import process from 'node:process';
|
|
||||||
|
|
||||||
if (process.env.APP_ENV === 'test') {
|
if (process.env.APP_ENV === 'test') {
|
||||||
dotenv.config({ path: path.resolve(__dirname, '../../.env.test') });
|
dotenv.config({ path: path.resolve(__dirname, '../../.env.test') });
|
||||||
@@ -9,6 +8,57 @@ if (process.env.APP_ENV === 'test') {
|
|||||||
dotenv.config();
|
dotenv.config();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppConfig = {
|
||||||
|
host: string;
|
||||||
|
protocol: string;
|
||||||
|
port: string;
|
||||||
|
webAppUrl: string;
|
||||||
|
webhookUrl: string;
|
||||||
|
appEnv: string;
|
||||||
|
logLevel: string;
|
||||||
|
isDev: boolean;
|
||||||
|
isTest: boolean;
|
||||||
|
isProd: boolean;
|
||||||
|
postgresDatabase: string;
|
||||||
|
postgresSchema: string;
|
||||||
|
postgresPort: number;
|
||||||
|
postgresHost: string;
|
||||||
|
postgresUsername: string;
|
||||||
|
postgresPassword?: string;
|
||||||
|
version: string;
|
||||||
|
postgresEnableSsl: boolean;
|
||||||
|
baseUrl: string;
|
||||||
|
encryptionKey: string;
|
||||||
|
webhookSecretKey: string;
|
||||||
|
appSecretKey: string;
|
||||||
|
serveWebAppSeparately: boolean;
|
||||||
|
redisHost: string;
|
||||||
|
redisPort: number;
|
||||||
|
redisUsername: string;
|
||||||
|
redisPassword: string;
|
||||||
|
redisTls: boolean;
|
||||||
|
enableBullMQDashboard: boolean;
|
||||||
|
bullMQDashboardUsername: string;
|
||||||
|
bullMQDashboardPassword: string;
|
||||||
|
telemetryEnabled: boolean;
|
||||||
|
requestBodySizeLimit: string;
|
||||||
|
smtpHost: string;
|
||||||
|
smtpPort: number;
|
||||||
|
smtpSecure: boolean;
|
||||||
|
smtpUser: string;
|
||||||
|
smtpPassword: string;
|
||||||
|
fromEmail: string;
|
||||||
|
isCloud: boolean;
|
||||||
|
isMation: boolean;
|
||||||
|
isSelfHosted: boolean;
|
||||||
|
paddleVendorId: number;
|
||||||
|
paddleVendorAuthCode: string;
|
||||||
|
paddlePublicKey: string;
|
||||||
|
licenseKey: string;
|
||||||
|
sentryDsn: string;
|
||||||
|
CI: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const host = process.env.HOST || 'localhost';
|
const host = process.env.HOST || 'localhost';
|
||||||
const protocol = process.env.PROTOCOL || 'http';
|
const protocol = process.env.PROTOCOL || 'http';
|
||||||
const port = process.env.PORT || '3000';
|
const port = process.env.PORT || '3000';
|
||||||
@@ -35,7 +85,7 @@ webhookUrl = webhookUrl.substring(0, webhookUrl.length - 1);
|
|||||||
|
|
||||||
const appEnv = process.env.APP_ENV || 'development';
|
const appEnv = process.env.APP_ENV || 'development';
|
||||||
|
|
||||||
const appConfig = {
|
const appConfig: AppConfig = {
|
||||||
host,
|
host,
|
||||||
protocol,
|
protocol,
|
||||||
port,
|
port,
|
@@ -4,10 +4,11 @@ import process from 'process';
|
|||||||
import pg from 'pg';
|
import pg from 'pg';
|
||||||
pg.types.setTypeParser(20, 'text', parseInt);
|
pg.types.setTypeParser(20, 'text', parseInt);
|
||||||
import knex from 'knex';
|
import knex from 'knex';
|
||||||
|
import type { Knex } from 'knex';
|
||||||
import knexConfig from '../../knexfile';
|
import knexConfig from '../../knexfile';
|
||||||
import logger from '../helpers/logger';
|
import logger from '../helpers/logger';
|
||||||
|
|
||||||
export const client = knex(knexConfig);
|
export const client: Knex = knex(knexConfig);
|
||||||
|
|
||||||
const CONNECTION_REFUSED = 'ECONNREFUSED';
|
const CONNECTION_REFUSED = 'ECONNREFUSED';
|
||||||
|
|
@@ -1,6 +1,16 @@
|
|||||||
import appConfig from './app';
|
import appConfig from './app';
|
||||||
|
|
||||||
const redisConfig = {
|
type TRedisConfig = {
|
||||||
|
host: string,
|
||||||
|
port: number,
|
||||||
|
username?: string,
|
||||||
|
password?: string,
|
||||||
|
tls?: Record<string, unknown>,
|
||||||
|
enableReadyCheck?: boolean,
|
||||||
|
enableOfflineQueue: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
const redisConfig: TRedisConfig = {
|
||||||
host: appConfig.redisHost,
|
host: appConfig.redisHost,
|
||||||
port: appConfig.redisPort,
|
port: appConfig.redisPort,
|
||||||
username: appConfig.redisUsername,
|
username: appConfig.redisUsername,
|
@@ -1,9 +1,11 @@
|
|||||||
|
import { Response } from 'express';
|
||||||
|
import { IJSONObject, IRequest } from '@automatisch/types';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import { serialize } from 'php-serialize';
|
import { serialize } from 'php-serialize';
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
import Billing from '../../helpers/billing/index.ee';
|
||||||
import appConfig from '../../config/app';
|
import appConfig from '../../config/app';
|
||||||
|
|
||||||
export default async (request, response) => {
|
export default async (request: IRequest, response: Response) => {
|
||||||
if (!verifyWebhook(request)) {
|
if (!verifyWebhook(request)) {
|
||||||
return response.sendStatus(401);
|
return response.sendStatus(401);
|
||||||
}
|
}
|
||||||
@@ -21,14 +23,14 @@ export default async (request, response) => {
|
|||||||
return response.sendStatus(200);
|
return response.sendStatus(200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const verifyWebhook = (request) => {
|
const verifyWebhook = (request: IRequest) => {
|
||||||
const signature = request.body.p_signature;
|
const signature = request.body.p_signature;
|
||||||
|
|
||||||
const keys = Object.keys(request.body)
|
const keys = Object.keys(request.body)
|
||||||
.filter((key) => key !== 'p_signature')
|
.filter((key) => key !== 'p_signature')
|
||||||
.sort();
|
.sort();
|
||||||
|
|
||||||
const sorted = {};
|
const sorted: IJSONObject = {};
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
sorted[key] = request.body[key];
|
sorted[key] = request.body[key];
|
||||||
});
|
});
|
@@ -1,10 +1,12 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
import { Response } from 'express';
|
||||||
|
import { IRequest } from '@automatisch/types';
|
||||||
|
|
||||||
import Connection from '../../models/connection';
|
import Connection from '../../models/connection';
|
||||||
import logger from '../../helpers/logger';
|
import logger from '../../helpers/logger';
|
||||||
import handler from '../../helpers/webhook-handler';
|
import handler from '../../helpers/webhook-handler';
|
||||||
|
|
||||||
export default async (request, response) => {
|
export default async (request: IRequest, response: Response) => {
|
||||||
const computedRequestPayload = {
|
const computedRequestPayload = {
|
||||||
headers: request.headers,
|
headers: request.headers,
|
||||||
body: request.body,
|
body: request.body,
|
||||||
@@ -20,7 +22,7 @@ export default async (request, response) => {
|
|||||||
.findById(connectionId)
|
.findById(connectionId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
if (!(await connection.verifyWebhook(request))) {
|
if (!await connection.verifyWebhook(request)) {
|
||||||
return response.sendStatus(401);
|
return response.sendStatus(401);
|
||||||
}
|
}
|
||||||
|
|
@@ -1,8 +1,11 @@
|
|||||||
|
import { Response } from 'express';
|
||||||
|
import { IRequest } from '@automatisch/types';
|
||||||
|
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
import logger from '../../helpers/logger';
|
import logger from '../../helpers/logger';
|
||||||
import handler from '../../helpers/webhook-handler';
|
import handler from '../../helpers/webhook-handler';
|
||||||
|
|
||||||
export default async (request, response) => {
|
export default async (request: IRequest, response: Response) => {
|
||||||
const computedRequestPayload = {
|
const computedRequestPayload = {
|
||||||
headers: request.headers,
|
headers: request.headers,
|
||||||
body: request.body,
|
body: request.body,
|
@@ -1,22 +1,22 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
|
||||||
export default class BaseError extends Error {
|
export default class BaseError extends Error {
|
||||||
details = {};
|
details = {};
|
||||||
|
statusCode?: number;
|
||||||
|
|
||||||
constructor(error) {
|
constructor(error?: string | IJSONObject) {
|
||||||
let computedError;
|
let computedError: Record<string, unknown>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
computedError = JSON.parse(error);
|
computedError = JSON.parse(error as string);
|
||||||
} catch {
|
} catch {
|
||||||
computedError =
|
computedError = (typeof error === 'string' || Array.isArray(error)) ? { error } : error;
|
||||||
typeof error === 'string' || Array.isArray(error) ? { error } : error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let computedMessage;
|
let computedMessage: string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// challenge to input to see if it is stringified JSON
|
// challenge to input to see if it is stringified JSON
|
||||||
JSON.parse(error);
|
JSON.parse(error as string);
|
||||||
computedMessage = error;
|
computedMessage = error as string;
|
||||||
} catch {
|
} catch {
|
||||||
if (typeof error === 'string') {
|
if (typeof error === 'string') {
|
||||||
computedMessage = error;
|
computedMessage = error;
|
@@ -1,10 +0,0 @@
|
|||||||
import BaseError from './base';
|
|
||||||
|
|
||||||
export default class GenerateAuthUrlError extends BaseError {
|
|
||||||
constructor(error) {
|
|
||||||
const computedError = error.response?.data || error.message;
|
|
||||||
super(computedError);
|
|
||||||
|
|
||||||
this.message = `Error occured while creating authorization URL!`;
|
|
||||||
}
|
|
||||||
}
|
|
14
packages/backend/src/errors/generate-auth-url.ts
Normal file
14
packages/backend/src/errors/generate-auth-url.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import BaseError from './base';
|
||||||
|
|
||||||
|
export default class GenerateAuthUrlError extends BaseError {
|
||||||
|
constructor(error: IJSONObject) {
|
||||||
|
const computedError =
|
||||||
|
((error.response as IJSONObject)?.data as IJSONObject) ||
|
||||||
|
(error.message as string);
|
||||||
|
|
||||||
|
super(computedError);
|
||||||
|
|
||||||
|
this.message = `Error occured while creating authorization URL!`;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,10 +0,0 @@
|
|||||||
import BaseError from './base';
|
|
||||||
|
|
||||||
export default class HttpError extends BaseError {
|
|
||||||
constructor(error) {
|
|
||||||
const computedError = error.response?.data || error.message;
|
|
||||||
super(computedError);
|
|
||||||
|
|
||||||
this.response = error.response;
|
|
||||||
}
|
|
||||||
}
|
|
17
packages/backend/src/errors/http.ts
Normal file
17
packages/backend/src/errors/http.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import type { AxiosResponse, AxiosError } from 'axios';
|
||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import BaseError from './base';
|
||||||
|
|
||||||
|
export default class HttpError extends BaseError {
|
||||||
|
response: AxiosResponse;
|
||||||
|
|
||||||
|
constructor(error: AxiosError) {
|
||||||
|
const computedError =
|
||||||
|
error.response?.data as IJSONObject ||
|
||||||
|
error.message as string;
|
||||||
|
|
||||||
|
super(computedError);
|
||||||
|
|
||||||
|
this.response = error.response;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,17 +0,0 @@
|
|||||||
import AppConfig from '../../models/app-config';
|
|
||||||
|
|
||||||
const createAppAuthClient = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('update', 'App');
|
|
||||||
|
|
||||||
const appConfig = await AppConfig.query()
|
|
||||||
.findById(params.input.appConfigId)
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
const appAuthClient = await appConfig
|
|
||||||
.$relatedQuery('appAuthClients')
|
|
||||||
.insert(params.input);
|
|
||||||
|
|
||||||
return appAuthClient;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createAppAuthClient;
|
|
@@ -0,0 +1,35 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
appConfigId: string;
|
||||||
|
name: string;
|
||||||
|
formattedAuthDefaults?: IJSONObject;
|
||||||
|
active?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createAppAuthClient = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
context.currentUser.can('update', 'App');
|
||||||
|
|
||||||
|
const appConfig = await AppConfig
|
||||||
|
.query()
|
||||||
|
.findById(params.input.appConfigId)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
const appAuthClient = await appConfig
|
||||||
|
.$relatedQuery('appAuthClients')
|
||||||
|
.insert(
|
||||||
|
params.input
|
||||||
|
);
|
||||||
|
|
||||||
|
return appAuthClient;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createAppAuthClient;
|
@@ -1,18 +0,0 @@
|
|||||||
import App from '../../models/app';
|
|
||||||
import AppConfig from '../../models/app-config';
|
|
||||||
|
|
||||||
const createAppConfig = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('update', 'App');
|
|
||||||
|
|
||||||
const key = params.input.key;
|
|
||||||
|
|
||||||
const app = await App.findOneByKey(key);
|
|
||||||
|
|
||||||
if (!app) throw new Error('The app cannot be found!');
|
|
||||||
|
|
||||||
const appConfig = await AppConfig.query().insert(params.input);
|
|
||||||
|
|
||||||
return appConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createAppConfig;
|
|
@@ -0,0 +1,36 @@
|
|||||||
|
import App from '../../models/app';
|
||||||
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
key: string;
|
||||||
|
allowCustomConnection?: boolean;
|
||||||
|
shared?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createAppConfig = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
context.currentUser.can('update', 'App');
|
||||||
|
|
||||||
|
const key = params.input.key;
|
||||||
|
|
||||||
|
const app = await App.findOneByKey(key);
|
||||||
|
|
||||||
|
if (!app) throw new Error('The app cannot be found!');
|
||||||
|
|
||||||
|
const appConfig = await AppConfig
|
||||||
|
.query()
|
||||||
|
.insert(
|
||||||
|
params.input
|
||||||
|
);
|
||||||
|
|
||||||
|
return appConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createAppConfig;
|
@@ -1,7 +1,21 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import AppConfig from '../../models/app-config';
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const createConnection = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
key: string;
|
||||||
|
appAuthClientId: string;
|
||||||
|
formattedData: IJSONObject;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createConnection = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Connection');
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
const { key, appAuthClientId } = params.input;
|
const { key, appAuthClientId } = params.input;
|
||||||
@@ -12,20 +26,16 @@ const createConnection = async (_parent, params, context) => {
|
|||||||
|
|
||||||
let formattedData = params.input.formattedData;
|
let formattedData = params.input.formattedData;
|
||||||
if (appConfig) {
|
if (appConfig) {
|
||||||
if (appConfig.disabled)
|
if (appConfig.disabled) throw new Error('This application has been disabled for new connections!');
|
||||||
throw new Error(
|
|
||||||
'This application has been disabled for new connections!'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!appConfig.allowCustomConnection && formattedData)
|
if (!appConfig.allowCustomConnection && formattedData) throw new Error(`Custom connections cannot be created for ${app.name}!`);
|
||||||
throw new Error(`Custom connections cannot be created for ${app.name}!`);
|
|
||||||
|
|
||||||
if (appConfig.shared && !formattedData) {
|
if (appConfig.shared && !formattedData) {
|
||||||
const authClient = await appConfig
|
const authClient = await appConfig
|
||||||
.$relatedQuery('appAuthClients')
|
.$relatedQuery('appAuthClients')
|
||||||
.findById(appAuthClientId)
|
.findById(appAuthClientId)
|
||||||
.where({
|
.where({
|
||||||
active: true,
|
active: true
|
||||||
})
|
})
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
@@ -33,7 +43,8 @@ const createConnection = async (_parent, params, context) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdConnection = await context.currentUser
|
const createdConnection = await context
|
||||||
|
.currentUser
|
||||||
.$relatedQuery('connections')
|
.$relatedQuery('connections')
|
||||||
.insert({
|
.insert({
|
||||||
key,
|
key,
|
@@ -1,7 +1,19 @@
|
|||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Step from '../../models/step';
|
import Step from '../../models/step';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const createFlow = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
triggerAppKey: string;
|
||||||
|
connectionId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createFlow = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Flow');
|
context.currentUser.can('create', 'Flow');
|
||||||
|
|
||||||
const connectionId = params?.input?.connectionId;
|
const connectionId = params?.input?.connectionId;
|
@@ -1,29 +0,0 @@
|
|||||||
import kebabCase from 'lodash/kebabCase';
|
|
||||||
import Role from '../../models/role';
|
|
||||||
|
|
||||||
const createRole = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('create', 'Role');
|
|
||||||
|
|
||||||
const { name, description, permissions } = params.input;
|
|
||||||
const key = kebabCase(name);
|
|
||||||
|
|
||||||
const existingRole = await Role.query().findOne({ key });
|
|
||||||
|
|
||||||
if (existingRole) {
|
|
||||||
throw new Error('Role already exists!');
|
|
||||||
}
|
|
||||||
|
|
||||||
return await Role.query()
|
|
||||||
.insertGraph(
|
|
||||||
{
|
|
||||||
key,
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
permissions,
|
|
||||||
},
|
|
||||||
{ relate: ['permissions'] }
|
|
||||||
)
|
|
||||||
.returning('*');
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createRole;
|
|
34
packages/backend/src/graphql/mutations/create-role.ee.ts
Normal file
34
packages/backend/src/graphql/mutations/create-role.ee.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import kebabCase from 'lodash/kebabCase';
|
||||||
|
import Permission from '../../models/permission';
|
||||||
|
import Role from '../../models/role';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
permissions: Permission[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createRole = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
|
context.currentUser.can('create', 'Role');
|
||||||
|
|
||||||
|
const { name, description, permissions } = params.input;
|
||||||
|
const key = kebabCase(name);
|
||||||
|
|
||||||
|
const existingRole = await Role.query().findOne({ key });
|
||||||
|
|
||||||
|
if (existingRole) {
|
||||||
|
throw new Error('Role already exists!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Role.query().insertGraph({
|
||||||
|
key,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
permissions,
|
||||||
|
}, { relate: ['permissions'] }).returning('*');
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createRole;
|
@@ -1,7 +1,28 @@
|
|||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const createStep = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
key: string;
|
||||||
|
appKey: string;
|
||||||
|
flow: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
connection: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
previousStep: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createStep = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('update', 'Flow');
|
const conditions = context.currentUser.can('update', 'Flow');
|
||||||
const userFlows = context.currentUser.$relatedQuery('flows');
|
const userFlows = context.currentUser.$relatedQuery('flows');
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
@@ -1,7 +1,23 @@
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import Role from '../../models/role';
|
import Role from '../../models/role';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const createUser = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
fullName: string;
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
role: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const createUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'User');
|
context.currentUser.can('create', 'User');
|
||||||
|
|
||||||
const { fullName, email, password } = params.input;
|
const { fullName, email, password } = params.input;
|
||||||
@@ -14,7 +30,7 @@ const createUser = async (_parent, params, context) => {
|
|||||||
throw new Error('User already exists!');
|
throw new Error('User already exists!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const userPayload = {
|
const userPayload: Partial<User> = {
|
||||||
fullName,
|
fullName,
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
@@ -1,9 +1,21 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import AppAuthClient from '../../models/app-auth-client';
|
import AppAuthClient from '../../models/app-auth-client';
|
||||||
|
|
||||||
const deleteAppAuthClient = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteAppAuthClient = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('delete', 'App');
|
context.currentUser.can('delete', 'App');
|
||||||
|
|
||||||
await AppAuthClient.query()
|
await AppAuthClient
|
||||||
|
.query()
|
||||||
.delete()
|
.delete()
|
||||||
.findOne({
|
.findOne({
|
||||||
id: params.input.id,
|
id: params.input.id,
|
@@ -1,4 +1,16 @@
|
|||||||
const deleteConnection = async (_parent, params, context) => {
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteConnection = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('delete', 'Connection');
|
context.currentUser.can('delete', 'Connection');
|
||||||
|
|
||||||
await context.currentUser
|
await context.currentUser
|
@@ -1,11 +1,17 @@
|
|||||||
import { Duration } from 'luxon';
|
import { Duration } from 'luxon';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import deleteUserQueue from '../../queues/delete-user.ee';
|
import deleteUserQueue from '../../queues/delete-user.ee';
|
||||||
import flowQueue from '../../queues/flow';
|
import flowQueue from '../../queues/flow';
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
import Execution from '../../models/execution';
|
||||||
import ExecutionStep from '../../models/execution-step';
|
import ExecutionStep from '../../models/execution-step';
|
||||||
import appConfig from '../../config/app';
|
import appConfig from '../../config/app';
|
||||||
|
|
||||||
const deleteCurrentUser = async (_parent, params, context) => {
|
const deleteCurrentUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: never,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const id = context.currentUser.id;
|
const id = context.currentUser.id;
|
||||||
|
|
||||||
const flows = await context.currentUser.$relatedQuery('flows').where({
|
const flows = await context.currentUser.$relatedQuery('flows').where({
|
||||||
@@ -26,7 +32,7 @@ const deleteCurrentUser = async (_parent, params, context) => {
|
|||||||
await context.currentUser
|
await context.currentUser
|
||||||
.$relatedQuery('executions')
|
.$relatedQuery('executions')
|
||||||
.select('executions.id')
|
.select('executions.id')
|
||||||
).map((execution) => execution.id);
|
).map((execution: Execution) => execution.id);
|
||||||
const flowIds = flows.map((flow) => flow.id);
|
const flowIds = flows.map((flow) => flow.id);
|
||||||
|
|
||||||
await ExecutionStep.query().delete().whereIn('execution_id', executionIds);
|
await ExecutionStep.query().delete().whereIn('execution_id', executionIds);
|
@@ -1,9 +1,21 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
import Execution from '../../models/execution';
|
||||||
import ExecutionStep from '../../models/execution-step';
|
import ExecutionStep from '../../models/execution-step';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
import logger from '../../helpers/logger';
|
import logger from '../../helpers/logger';
|
||||||
|
|
||||||
const deleteFlow = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteFlow = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('delete', 'Flow');
|
const conditions = context.currentUser.can('delete', 'Flow');
|
||||||
const isCreator = conditions.isCreator;
|
const isCreator = conditions.isCreator;
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
||||||
@@ -31,15 +43,13 @@ const deleteFlow = async (_parent, params, context) => {
|
|||||||
await trigger.unregisterHook($);
|
await trigger.unregisterHook($);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// suppress error as the remote resource might have been already deleted
|
// suppress error as the remote resource might have been already deleted
|
||||||
logger.debug(
|
logger.debug(`Failed to unregister webhook for flow ${flow.id}: ${error.message}`);
|
||||||
`Failed to unregister webhook for flow ${flow.id}: ${error.message}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const executionIds = (
|
const executionIds = (
|
||||||
await flow.$relatedQuery('executions').select('executions.id')
|
await flow.$relatedQuery('executions').select('executions.id')
|
||||||
).map((execution) => execution.id);
|
).map((execution: Execution) => execution.id);
|
||||||
|
|
||||||
await ExecutionStep.query().delete().whereIn('execution_id', executionIds);
|
await ExecutionStep.query().delete().whereIn('execution_id', executionIds);
|
||||||
|
|
@@ -1,7 +1,18 @@
|
|||||||
import Role from '../../models/role';
|
import Role from '../../models/role';
|
||||||
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const deleteRole = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteRole = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('delete', 'Role');
|
context.currentUser.can('delete', 'Role');
|
||||||
|
|
||||||
const role = await Role.query().findById(params.input.id).throwIfNotFound();
|
const role = await Role.query().findById(params.input.id).throwIfNotFound();
|
@@ -1,4 +1,16 @@
|
|||||||
const deleteStep = async (_parent, params, context) => {
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteStep = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('update', 'Flow');
|
context.currentUser.can('update', 'Flow');
|
||||||
|
|
||||||
const step = await context.currentUser
|
const step = await context.currentUser
|
@@ -1,8 +1,19 @@
|
|||||||
import { Duration } from 'luxon';
|
import { Duration } from 'luxon';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import deleteUserQueue from '../../queues/delete-user.ee';
|
import deleteUserQueue from '../../queues/delete-user.ee';
|
||||||
|
|
||||||
const deleteUser = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('delete', 'User');
|
context.currentUser.can('delete', 'User');
|
||||||
|
|
||||||
const id = params.input.id;
|
const id = params.input.id;
|
||||||
@@ -13,7 +24,7 @@ const deleteUser = async (_parent, params, context) => {
|
|||||||
const jobPayload = { id };
|
const jobPayload = { id };
|
||||||
const millisecondsFor30Days = Duration.fromObject({ days: 30 }).toMillis();
|
const millisecondsFor30Days = Duration.fromObject({ days: 30 }).toMillis();
|
||||||
const jobOptions = {
|
const jobOptions = {
|
||||||
delay: millisecondsFor30Days,
|
delay: millisecondsFor30Days
|
||||||
};
|
};
|
||||||
|
|
||||||
await deleteUserQueue.add(jobName, jobPayload, jobOptions);
|
await deleteUserQueue.add(jobName, jobPayload, jobOptions);
|
@@ -1,4 +1,15 @@
|
|||||||
function updateStepId(value, newStepIds) {
|
import Context from '../../types/express/context';
|
||||||
|
import Step from '../../models/step';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type NewStepIds = Record<string, string>;
|
||||||
|
|
||||||
|
function updateStepId(value: string, newStepIds: NewStepIds) {
|
||||||
let newValue = value;
|
let newValue = value;
|
||||||
|
|
||||||
const stepIdEntries = Object.entries(newStepIds);
|
const stepIdEntries = Object.entries(newStepIds);
|
||||||
@@ -13,9 +24,9 @@ function updateStepId(value, newStepIds) {
|
|||||||
return newValue;
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStepVariables(parameters, newStepIds) {
|
function updateStepVariables(parameters: Step['parameters'], newStepIds: NewStepIds): Step['parameters'] {
|
||||||
const entries = Object.entries(parameters);
|
const entries = Object.entries(parameters);
|
||||||
return entries.reduce((result, [key, value]) => {
|
return entries.reduce((result, [key, value]: [string, unknown]) => {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
@@ -26,7 +37,7 @@ function updateStepVariables(parameters, newStepIds) {
|
|||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
[key]: value.map((item) => updateStepVariables(item, newStepIds)),
|
[key]: value.map(item => updateStepVariables(item, newStepIds)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +48,11 @@ function updateStepVariables(parameters, newStepIds) {
|
|||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const duplicateFlow = async (_parent, params, context) => {
|
const duplicateFlow = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Flow');
|
context.currentUser.can('create', 'Flow');
|
||||||
|
|
||||||
const flow = await context.currentUser
|
const flow = await context.currentUser
|
||||||
@@ -54,16 +69,17 @@ const duplicateFlow = async (_parent, params, context) => {
|
|||||||
active: false,
|
active: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const newStepIds = {};
|
const newStepIds: NewStepIds = {};
|
||||||
for (const step of flow.steps) {
|
for (const step of flow.steps) {
|
||||||
const duplicatedStep = await duplicatedFlow.$relatedQuery('steps').insert({
|
const duplicatedStep = await duplicatedFlow.$relatedQuery('steps')
|
||||||
key: step.key,
|
.insert({
|
||||||
appKey: step.appKey,
|
key: step.key,
|
||||||
type: step.type,
|
appKey: step.appKey,
|
||||||
connectionId: step.connectionId,
|
type: step.type,
|
||||||
position: step.position,
|
connectionId: step.connectionId,
|
||||||
parameters: updateStepVariables(step.parameters, newStepIds),
|
position: step.position,
|
||||||
});
|
parameters: updateStepVariables(step.parameters, newStepIds),
|
||||||
|
});
|
||||||
|
|
||||||
if (duplicatedStep.isTrigger) {
|
if (duplicatedStep.isTrigger) {
|
||||||
await duplicatedStep.updateWebhookUrl();
|
await duplicatedStep.updateWebhookUrl();
|
@@ -1,7 +1,18 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import testRun from '../../services/test-run';
|
import testRun from '../../services/test-run';
|
||||||
import Step from '../../models/step';
|
import Step from '../../models/step';
|
||||||
|
|
||||||
const executeFlow = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
stepId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const executeFlow = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('update', 'Flow');
|
const conditions = context.currentUser.can('update', 'Flow');
|
||||||
const isCreator = conditions.isCreator;
|
const isCreator = conditions.isCreator;
|
||||||
const allSteps = Step.query();
|
const allSteps = Step.query();
|
||||||
@@ -10,7 +21,10 @@ const executeFlow = async (_parent, params, context) => {
|
|||||||
|
|
||||||
const { stepId } = params.input;
|
const { stepId } = params.input;
|
||||||
|
|
||||||
const untilStep = await baseQuery.clone().findById(stepId).throwIfNotFound();
|
const untilStep = await baseQuery
|
||||||
|
.clone()
|
||||||
|
.findById(stepId)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
const { executionStep } = await testRun({ stepId });
|
const { executionStep } = await testRun({ stepId });
|
||||||
|
|
@@ -6,7 +6,13 @@ import {
|
|||||||
REMOVE_AFTER_7_DAYS_OR_50_JOBS,
|
REMOVE_AFTER_7_DAYS_OR_50_JOBS,
|
||||||
} from '../../helpers/remove-job-configuration';
|
} from '../../helpers/remove-job-configuration';
|
||||||
|
|
||||||
const forgotPassword = async (_parent, params) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
email: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const forgotPassword = async (_parent: unknown, params: Params) => {
|
||||||
const { email } = params.input;
|
const { email } = params.input;
|
||||||
|
|
||||||
const user = await User.query().findOne({ email: email.toLowerCase() });
|
const user = await User.query().findOne({ email: email.toLowerCase() });
|
@@ -1,7 +1,18 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
|
|
||||||
const generateAuthUrl = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateAuthUrl = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Connection');
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
const connection = await context.currentUser
|
const connection = await context.currentUser
|
@@ -1,7 +1,14 @@
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import createAuthTokenByUserId from '../../helpers/create-auth-token-by-user-id';
|
import createAuthTokenByUserId from '../../helpers/create-auth-token-by-user-id';
|
||||||
|
|
||||||
const login = async (_parent, params) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const login = async (_parent: unknown, params: Params) => {
|
||||||
const user = await User.query().findOne({
|
const user = await User.query().findOne({
|
||||||
email: params.input.email.toLowerCase(),
|
email: params.input.email.toLowerCase(),
|
||||||
});
|
});
|
@@ -1,7 +1,15 @@
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
import Role from '../../models/role';
|
import Role from '../../models/role';
|
||||||
|
|
||||||
const registerUser = async (_parent, params) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
fullName: string;
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerUser = async (_parent: unknown, params: Params) => {
|
||||||
const { fullName, email, password } = params.input;
|
const { fullName, email, password } = params.input;
|
||||||
|
|
||||||
const existingUser = await User.query().findOne({
|
const existingUser = await User.query().findOne({
|
@@ -1,4 +1,16 @@
|
|||||||
const resetConnection = async (_parent, params, context) => {
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetConnection = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Connection');
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
let connection = await context.currentUser
|
let connection = await context.currentUser
|
@@ -1,6 +1,13 @@
|
|||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
|
|
||||||
const resetPassword = async (_parent, params) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
token: string;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetPassword = async (_parent: unknown, params: Params) => {
|
||||||
const { token, password } = params.input;
|
const { token, password } = params.input;
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
@@ -1,17 +0,0 @@
|
|||||||
import AppAuthClient from '../../models/app-auth-client';
|
|
||||||
|
|
||||||
const updateAppAuthClient = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('update', 'App');
|
|
||||||
|
|
||||||
const { id, ...appAuthClientData } = params.input;
|
|
||||||
|
|
||||||
const appAuthClient = await AppAuthClient.query()
|
|
||||||
.findById(id)
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
await appAuthClient.$query().patch(appAuthClientData);
|
|
||||||
|
|
||||||
return appAuthClient;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default updateAppAuthClient;
|
|
@@ -0,0 +1,38 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import AppAuthClient from '../../models/app-auth-client';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
formattedAuthDefaults?: IJSONObject;
|
||||||
|
active?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateAppAuthClient = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
context.currentUser.can('update', 'App');
|
||||||
|
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
...appAuthClientData
|
||||||
|
} = params.input;
|
||||||
|
|
||||||
|
const appAuthClient = await AppAuthClient
|
||||||
|
.query()
|
||||||
|
.findById(id)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
await appAuthClient
|
||||||
|
.$query()
|
||||||
|
.patch(appAuthClientData);
|
||||||
|
|
||||||
|
return appAuthClient;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default updateAppAuthClient;
|
@@ -1,15 +0,0 @@
|
|||||||
import AppConfig from '../../models/app-config';
|
|
||||||
|
|
||||||
const updateAppConfig = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('update', 'App');
|
|
||||||
|
|
||||||
const { id, ...appConfigToUpdate } = params.input;
|
|
||||||
|
|
||||||
const appConfig = await AppConfig.query().findById(id).throwIfNotFound();
|
|
||||||
|
|
||||||
await appConfig.$query().patch(appConfigToUpdate);
|
|
||||||
|
|
||||||
return appConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default updateAppConfig;
|
|
@@ -0,0 +1,39 @@
|
|||||||
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
allowCustomConnection?: boolean;
|
||||||
|
shared?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateAppConfig = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
context.currentUser.can('update', 'App');
|
||||||
|
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
...appConfigToUpdate
|
||||||
|
} = params.input;
|
||||||
|
|
||||||
|
const appConfig = await AppConfig
|
||||||
|
.query()
|
||||||
|
.findById(id)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
|
await appConfig
|
||||||
|
.$query()
|
||||||
|
.patch(
|
||||||
|
appConfigToUpdate
|
||||||
|
);
|
||||||
|
|
||||||
|
return appConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default updateAppConfig;
|
@@ -1,6 +1,18 @@
|
|||||||
|
import type { IJSONValue } from '@automatisch/types';
|
||||||
import Config from '../../models/config';
|
import Config from '../../models/config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const updateConfig = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
[index: string]: IJSONValue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateConfig = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('update', 'Config');
|
context.currentUser.can('update', 'Config');
|
||||||
|
|
||||||
const config = params.input;
|
const config = params.input;
|
@@ -1,6 +1,20 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import AppAuthClient from '../../models/app-auth-client';
|
import AppAuthClient from '../../models/app-auth-client';
|
||||||
|
|
||||||
const updateConnection = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
formattedData?: IJSONObject;
|
||||||
|
appAuthClientId?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateConnection = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Connection');
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
let connection = await context.currentUser
|
let connection = await context.currentUser
|
||||||
@@ -13,7 +27,8 @@ const updateConnection = async (_parent, params, context) => {
|
|||||||
let formattedData = params.input.formattedData;
|
let formattedData = params.input.formattedData;
|
||||||
|
|
||||||
if (params.input.appAuthClientId) {
|
if (params.input.appAuthClientId) {
|
||||||
const appAuthClient = await AppAuthClient.query()
|
const appAuthClient = await AppAuthClient
|
||||||
|
.query()
|
||||||
.findById(params.input.appAuthClientId)
|
.findById(params.input.appAuthClientId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
const updateCurrentUser = async (_parent, params, context) => {
|
|
||||||
const user = await context.currentUser.$query().patchAndFetch({
|
|
||||||
email: params.input.email,
|
|
||||||
password: params.input.password,
|
|
||||||
fullName: params.input.fullName,
|
|
||||||
});
|
|
||||||
|
|
||||||
return user;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default updateCurrentUser;
|
|
@@ -0,0 +1,25 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
fullName: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCurrentUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
const user = await context.currentUser.$query().patchAndFetch({
|
||||||
|
email: params.input.email,
|
||||||
|
password: params.input.password,
|
||||||
|
fullName: params.input.fullName,
|
||||||
|
});
|
||||||
|
|
||||||
|
return user;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default updateCurrentUser;
|
@@ -1,15 +1,24 @@
|
|||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import flowQueue from '../../queues/flow';
|
import flowQueue from '../../queues/flow';
|
||||||
import {
|
import { REMOVE_AFTER_30_DAYS_OR_150_JOBS, REMOVE_AFTER_7_DAYS_OR_50_JOBS } from '../../helpers/remove-job-configuration';
|
||||||
REMOVE_AFTER_30_DAYS_OR_150_JOBS,
|
|
||||||
REMOVE_AFTER_7_DAYS_OR_50_JOBS,
|
|
||||||
} from '../../helpers/remove-job-configuration';
|
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
active: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const JOB_NAME = 'flow';
|
const JOB_NAME = 'flow';
|
||||||
const EVERY_15_MINUTES_CRON = '*/15 * * * *';
|
const EVERY_15_MINUTES_CRON = '*/15 * * * *';
|
||||||
|
|
||||||
const updateFlowStatus = async (_parent, params, context) => {
|
const updateFlowStatus = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('publish', 'Flow');
|
const conditions = context.currentUser.can('publish', 'Flow');
|
||||||
const isCreator = conditions.isCreator;
|
const isCreator = conditions.isCreator;
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
||||||
@@ -65,7 +74,7 @@ const updateFlowStatus = async (_parent, params, context) => {
|
|||||||
repeat: repeatOptions,
|
repeat: repeatOptions,
|
||||||
jobId: flow.id,
|
jobId: flow.id,
|
||||||
removeOnComplete: REMOVE_AFTER_7_DAYS_OR_50_JOBS,
|
removeOnComplete: REMOVE_AFTER_7_DAYS_OR_50_JOBS,
|
||||||
removeOnFail: REMOVE_AFTER_30_DAYS_OR_150_JOBS,
|
removeOnFail: REMOVE_AFTER_30_DAYS_OR_150_JOBS
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -76,9 +85,12 @@ const updateFlowStatus = async (_parent, params, context) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flow = await flow.$query().withGraphFetched('steps').patchAndFetch({
|
flow = await flow
|
||||||
active: newActiveValue,
|
.$query()
|
||||||
});
|
.withGraphFetched('steps')
|
||||||
|
.patchAndFetch({
|
||||||
|
active: newActiveValue,
|
||||||
|
});
|
||||||
|
|
||||||
return flow;
|
return flow;
|
||||||
};
|
};
|
@@ -1,4 +1,17 @@
|
|||||||
const updateFlow = async (_parent, params, context) => {
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateFlow = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('update', 'Flow');
|
context.currentUser.can('update', 'Flow');
|
||||||
|
|
||||||
let flow = await context.currentUser
|
let flow = await context.currentUser
|
@@ -1,13 +1,35 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import Role from '../../models/role';
|
import Role from '../../models/role';
|
||||||
import Permission from '../../models/permission';
|
import Permission from '../../models/permission';
|
||||||
import permissionCatalog from '../../helpers/permission-catalog.ee';
|
import permissionCatalog from '../../helpers/permission-catalog.ee';
|
||||||
|
|
||||||
const updateRole = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
permissions: Permission[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateRole = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('update', 'Role');
|
context.currentUser.can('update', 'Role');
|
||||||
|
|
||||||
const { id, name, description, permissions } = params.input;
|
const {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
permissions,
|
||||||
|
} = params.input;
|
||||||
|
|
||||||
const role = await Role.query().findById(id).throwIfNotFound();
|
const role = await Role
|
||||||
|
.query()
|
||||||
|
.findById(id)
|
||||||
|
.throwIfNotFound();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updatedRole = await Role.transaction(async (trx) => {
|
const updatedRole = await Role.transaction(async (trx) => {
|
||||||
@@ -16,17 +38,19 @@ const updateRole = async (_parent, params, context) => {
|
|||||||
if (permissions?.length) {
|
if (permissions?.length) {
|
||||||
const sanitizedPermissions = permissions
|
const sanitizedPermissions = permissions
|
||||||
.filter((permission) => {
|
.filter((permission) => {
|
||||||
const { action, subject, conditions } = permission;
|
const {
|
||||||
|
action,
|
||||||
|
subject,
|
||||||
|
conditions,
|
||||||
|
} = permission;
|
||||||
|
|
||||||
const relevantAction = permissionCatalog.actions.find(
|
const relevantAction = permissionCatalog.actions.find(actionCatalogItem => actionCatalogItem.key === action);
|
||||||
(actionCatalogItem) => actionCatalogItem.key === action
|
|
||||||
);
|
|
||||||
const validSubject = relevantAction.subjects.includes(subject);
|
const validSubject = relevantAction.subjects.includes(subject);
|
||||||
const validConditions = conditions.every((condition) => {
|
const validConditions = conditions.every(condition => {
|
||||||
return !!permissionCatalog.conditions.find(
|
return !!permissionCatalog
|
||||||
(conditionCatalogItem) => conditionCatalogItem.key === condition
|
.conditions
|
||||||
);
|
.find((conditionCatalogItem) => conditionCatalogItem.key === condition);
|
||||||
});
|
})
|
||||||
|
|
||||||
return validSubject && validConditions;
|
return validSubject && validConditions;
|
||||||
})
|
})
|
||||||
@@ -38,17 +62,22 @@ const updateRole = async (_parent, params, context) => {
|
|||||||
await Permission.query().insert(sanitizedPermissions);
|
await Permission.query().insert(sanitizedPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
await role.$query(trx).patch({
|
await role
|
||||||
name,
|
.$query(trx)
|
||||||
description,
|
.patch(
|
||||||
});
|
{
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return await Role.query(trx)
|
return await Role
|
||||||
|
.query(trx)
|
||||||
.leftJoinRelated({
|
.leftJoinRelated({
|
||||||
permissions: true,
|
permissions: true
|
||||||
})
|
})
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
permissions: true,
|
permissions: true
|
||||||
})
|
})
|
||||||
.findById(id);
|
.findById(id);
|
||||||
});
|
});
|
@@ -1,8 +1,29 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Step from '../../models/step';
|
import Step from '../../models/step';
|
||||||
import Connection from '../../models/connection';
|
import Connection from '../../models/connection';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const updateStep = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
appKey: string;
|
||||||
|
parameters: IJSONObject;
|
||||||
|
flow: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
connection: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateStep = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const { isCreator } = context.currentUser.can('update', 'Flow');
|
const { isCreator } = context.currentUser.can('update', 'Flow');
|
||||||
const userSteps = context.currentUser.$relatedQuery('steps');
|
const userSteps = context.currentUser.$relatedQuery('steps');
|
||||||
const allSteps = Step.query();
|
const allSteps = Step.query();
|
||||||
@@ -29,13 +50,11 @@ const updateStep = async (_parent, params, context) => {
|
|||||||
|
|
||||||
const userConnections = context.currentUser.$relatedQuery('connections');
|
const userConnections = context.currentUser.$relatedQuery('connections');
|
||||||
const allConnections = Connection.query();
|
const allConnections = Connection.query();
|
||||||
const baseConnectionsQuery = canSeeAllConnections
|
const baseConnectionsQuery = canSeeAllConnections ? allConnections : userConnections;
|
||||||
? allConnections
|
|
||||||
: userConnections;
|
|
||||||
|
|
||||||
const connection = await baseConnectionsQuery
|
const connection = await baseConnectionsQuery
|
||||||
.clone()
|
.clone()
|
||||||
.findById(input.connection?.id);
|
.findById(input.connection?.id)
|
||||||
|
|
||||||
if (!connection) {
|
if (!connection) {
|
||||||
throw new Error('The connection does not exist!');
|
throw new Error('The connection does not exist!');
|
@@ -1,9 +1,25 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import User from '../../models/user';
|
import User from '../../models/user';
|
||||||
|
|
||||||
const updateUser = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
fullName: string;
|
||||||
|
role: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('update', 'User');
|
context.currentUser.can('update', 'User');
|
||||||
|
|
||||||
const userPayload = {
|
const userPayload: Partial<User> = {
|
||||||
email: params.input.email,
|
email: params.input.email,
|
||||||
fullName: params.input.fullName,
|
fullName: params.input.fullName,
|
||||||
};
|
};
|
@@ -1,30 +0,0 @@
|
|||||||
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
|
||||||
|
|
||||||
const upsertSamlAuthProvider = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('create', 'SamlAuthProvider');
|
|
||||||
|
|
||||||
const samlAuthProviderPayload = {
|
|
||||||
...params.input,
|
|
||||||
};
|
|
||||||
|
|
||||||
const existingSamlAuthProvider = await SamlAuthProvider.query()
|
|
||||||
.limit(1)
|
|
||||||
.first();
|
|
||||||
|
|
||||||
if (!existingSamlAuthProvider) {
|
|
||||||
const samlAuthProvider = await SamlAuthProvider.query().insert(
|
|
||||||
samlAuthProviderPayload
|
|
||||||
);
|
|
||||||
|
|
||||||
return samlAuthProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
const samlAuthProvider = await SamlAuthProvider.query().patchAndFetchById(
|
|
||||||
existingSamlAuthProvider.id,
|
|
||||||
samlAuthProviderPayload
|
|
||||||
);
|
|
||||||
|
|
||||||
return samlAuthProvider;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default upsertSamlAuthProvider;
|
|
@@ -0,0 +1,52 @@
|
|||||||
|
import type { SamlConfig } from '@node-saml/passport-saml';
|
||||||
|
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
name: string;
|
||||||
|
certificate: string;
|
||||||
|
signatureAlgorithm: SamlConfig['signatureAlgorithm'];
|
||||||
|
issuer: string;
|
||||||
|
entryPoint: string;
|
||||||
|
firstnameAttributeName: string;
|
||||||
|
surnameAttributeName: string;
|
||||||
|
emailAttributeName: string;
|
||||||
|
roleAttributeName: string;
|
||||||
|
defaultRoleId: string;
|
||||||
|
active: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const upsertSamlAuthProvider = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
context.currentUser.can('create', 'SamlAuthProvider');
|
||||||
|
|
||||||
|
const samlAuthProviderPayload: Partial<SamlAuthProvider> = {
|
||||||
|
...params.input,
|
||||||
|
};
|
||||||
|
|
||||||
|
const existingSamlAuthProvider = await SamlAuthProvider.query()
|
||||||
|
.limit(1)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if (!existingSamlAuthProvider) {
|
||||||
|
const samlAuthProvider = await SamlAuthProvider.query().insert(
|
||||||
|
samlAuthProviderPayload
|
||||||
|
);
|
||||||
|
|
||||||
|
return samlAuthProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
const samlAuthProvider = await SamlAuthProvider.query().patchAndFetchById(
|
||||||
|
existingSamlAuthProvider.id,
|
||||||
|
samlAuthProviderPayload
|
||||||
|
);
|
||||||
|
|
||||||
|
return samlAuthProvider;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default upsertSamlAuthProvider;
|
@@ -1,11 +1,24 @@
|
|||||||
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
import SamlAuthProvider from '../../models/saml-auth-provider.ee';
|
||||||
import SamlAuthProvidersRoleMapping from '../../models/saml-auth-providers-role-mapping.ee';
|
import SamlAuthProvidersRoleMapping from '../../models/saml-auth-providers-role-mapping.ee';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
input: {
|
||||||
|
samlAuthProviderId: string;
|
||||||
|
samlAuthProvidersRoleMappings: [
|
||||||
|
{
|
||||||
|
roleId: string;
|
||||||
|
remoteRoleName: string;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const upsertSamlAuthProvidersRoleMappings = async (
|
const upsertSamlAuthProvidersRoleMappings = async (
|
||||||
_parent,
|
_parent: unknown,
|
||||||
params,
|
params: Params,
|
||||||
context
|
context: Context
|
||||||
) => {
|
) => {
|
||||||
context.currentUser.can('update', 'SamlAuthProvider');
|
context.currentUser.can('update', 'SamlAuthProvider');
|
||||||
|
|
@@ -1,7 +1,18 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
|
|
||||||
const verifyConnection = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
input: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const verifyConnection = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
context.currentUser.can('create', 'Connection');
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
let connection = await context.currentUser
|
let connection = await context.currentUser
|
@@ -1,6 +1,11 @@
|
|||||||
import AppAuthClient from '../../models/app-auth-client';
|
import AppAuthClient from '../../models/app-auth-client';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const getAppAuthClient = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAppAuthClient = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
let canSeeAllClients = false;
|
let canSeeAllClients = false;
|
||||||
try {
|
try {
|
||||||
context.currentUser.can('read', 'App');
|
context.currentUser.can('read', 'App');
|
||||||
@@ -10,7 +15,8 @@ const getAppAuthClient = async (_parent, params, context) => {
|
|||||||
// void
|
// void
|
||||||
}
|
}
|
||||||
|
|
||||||
const appAuthClient = AppAuthClient.query()
|
const appAuthClient = AppAuthClient
|
||||||
|
.query()
|
||||||
.findById(params.id)
|
.findById(params.id)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
@@ -1,6 +1,12 @@
|
|||||||
import AppConfig from '../../models/app-config';
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const getAppAuthClients = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
appKey: string;
|
||||||
|
active: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAppAuthClients = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
let canSeeAllClients = false;
|
let canSeeAllClients = false;
|
||||||
try {
|
try {
|
||||||
context.currentUser.can('read', 'App');
|
context.currentUser.can('read', 'App');
|
||||||
@@ -10,7 +16,8 @@ const getAppAuthClients = async (_parent, params, context) => {
|
|||||||
// void
|
// void
|
||||||
}
|
}
|
||||||
|
|
||||||
const appConfig = await AppConfig.query()
|
const appConfig = await AppConfig
|
||||||
|
.query()
|
||||||
.findOne({
|
.findOne({
|
||||||
key: params.appKey,
|
key: params.appKey,
|
||||||
})
|
})
|
||||||
@@ -23,8 +30,8 @@ const getAppAuthClients = async (_parent, params, context) => {
|
|||||||
|
|
||||||
if (!canSeeAllClients) {
|
if (!canSeeAllClients) {
|
||||||
appAuthClients.where({
|
appAuthClients.where({
|
||||||
active: true,
|
active: true
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return await appAuthClients;
|
return await appAuthClients;
|
@@ -1,17 +0,0 @@
|
|||||||
import AppConfig from '../../models/app-config';
|
|
||||||
|
|
||||||
const getAppConfig = async (_parent, params, context) => {
|
|
||||||
context.currentUser.can('create', 'Connection');
|
|
||||||
|
|
||||||
const appConfig = await AppConfig.query()
|
|
||||||
.withGraphFetched({
|
|
||||||
appAuthClients: true,
|
|
||||||
})
|
|
||||||
.findOne({
|
|
||||||
key: params.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
return appConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getAppConfig;
|
|
23
packages/backend/src/graphql/queries/get-app-config.ee.ts
Normal file
23
packages/backend/src/graphql/queries/get-app-config.ee.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import AppConfig from '../../models/app-config';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
key: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAppConfig = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
|
context.currentUser.can('create', 'Connection');
|
||||||
|
|
||||||
|
const appConfig = await AppConfig
|
||||||
|
.query()
|
||||||
|
.withGraphFetched({
|
||||||
|
appAuthClients: true
|
||||||
|
})
|
||||||
|
.findOne({
|
||||||
|
key: params.key
|
||||||
|
});
|
||||||
|
|
||||||
|
return appConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getAppConfig;
|
@@ -1,14 +1,17 @@
|
|||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Connection from '../../models/connection';
|
import Connection from '../../models/connection';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
const getApp = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
key: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getApp = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
const conditions = context.currentUser.can('read', 'Connection');
|
const conditions = context.currentUser.can('read', 'Connection');
|
||||||
|
|
||||||
const userConnections = context.currentUser.$relatedQuery('connections');
|
const userConnections = context.currentUser.$relatedQuery('connections');
|
||||||
const allConnections = Connection.query();
|
const allConnections = Connection.query();
|
||||||
const connectionBaseQuery = conditions.isCreator
|
const connectionBaseQuery = conditions.isCreator ? userConnections : allConnections;
|
||||||
? userConnections
|
|
||||||
: allConnections;
|
|
||||||
|
|
||||||
const app = await App.findOneByKey(params.key);
|
const app = await App.findOneByKey(params.key);
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ const getApp = async (_parent, params, context) => {
|
|||||||
.select('connections.*')
|
.select('connections.*')
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
appConfig: true,
|
appConfig: true,
|
||||||
appAuthClient: true,
|
appAuthClient: true
|
||||||
})
|
})
|
||||||
.fullOuterJoinRelated('steps')
|
.fullOuterJoinRelated('steps')
|
||||||
.where({
|
.where({
|
@@ -1,17 +0,0 @@
|
|||||||
import App from '../../models/app';
|
|
||||||
|
|
||||||
const getApps = async (_parent, params) => {
|
|
||||||
const apps = await App.findAll(params.name);
|
|
||||||
|
|
||||||
if (params.onlyWithTriggers) {
|
|
||||||
return apps.filter((app) => app.triggers?.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.onlyWithActions) {
|
|
||||||
return apps.filter((app) => app.actions?.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return apps;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getApps;
|
|
24
packages/backend/src/graphql/queries/get-apps.ts
Normal file
24
packages/backend/src/graphql/queries/get-apps.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { IApp } from '@automatisch/types';
|
||||||
|
import App from '../../models/app';
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
name: string;
|
||||||
|
onlyWithTriggers: boolean;
|
||||||
|
onlyWithActions: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getApps = async (_parent: unknown, params: Params) => {
|
||||||
|
const apps = await App.findAll(params.name);
|
||||||
|
|
||||||
|
if (params.onlyWithTriggers) {
|
||||||
|
return apps.filter((app: IApp) => app.triggers?.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.onlyWithActions) {
|
||||||
|
return apps.filter((app: IApp) => app.actions?.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getApps;
|
@@ -1,8 +1,17 @@
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
import { TSubscription } from '@automatisch/types';
|
||||||
import ExecutionStep from '../../models/execution-step';
|
|
||||||
|
|
||||||
const getBillingAndUsage = async (_parent, _params, context) => {
|
import Context from '../../types/express/context';
|
||||||
|
import Billing from '../../helpers/billing/index.ee';
|
||||||
|
import Execution from '../../models/execution';
|
||||||
|
import ExecutionStep from '../../models/execution-step';
|
||||||
|
import Subscription from '../../models/subscription.ee';
|
||||||
|
|
||||||
|
const getBillingAndUsage = async (
|
||||||
|
_parent: unknown,
|
||||||
|
_params: unknown,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const persistedSubscription = await context.currentUser.$relatedQuery(
|
const persistedSubscription = await context.currentUser.$relatedQuery(
|
||||||
'currentSubscription'
|
'currentSubscription'
|
||||||
);
|
);
|
||||||
@@ -19,7 +28,7 @@ const getBillingAndUsage = async (_parent, _params, context) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const paidSubscription = (subscription) => {
|
const paidSubscription = (subscription: Subscription): TSubscription => {
|
||||||
const currentPlan = Billing.paddlePlans.find(
|
const currentPlan = Billing.paddlePlans.find(
|
||||||
(plan) => plan.productId === subscription.paddlePlanId
|
(plan) => plan.productId === subscription.paddlePlanId
|
||||||
);
|
);
|
||||||
@@ -54,7 +63,7 @@ const paidSubscription = (subscription) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const freeTrialSubscription = () => {
|
const freeTrialSubscription = (): TSubscription => {
|
||||||
return {
|
return {
|
||||||
status: null,
|
status: null,
|
||||||
monthlyQuota: {
|
monthlyQuota: {
|
||||||
@@ -76,15 +85,15 @@ const freeTrialSubscription = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const executionIds = async (context) => {
|
const executionIds = async (context: Context) => {
|
||||||
return (
|
return (
|
||||||
await context.currentUser
|
await context.currentUser
|
||||||
.$relatedQuery('executions')
|
.$relatedQuery('executions')
|
||||||
.select('executions.id')
|
.select('executions.id')
|
||||||
).map((execution) => execution.id);
|
).map((execution: Execution) => execution.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const executionStepCount = async (context) => {
|
const executionStepCount = async (context: Context) => {
|
||||||
const executionStepCount = await ExecutionStep.query()
|
const executionStepCount = await ExecutionStep.query()
|
||||||
.whereIn('execution_id', await executionIds(context))
|
.whereIn('execution_id', await executionIds(context))
|
||||||
.andWhere(
|
.andWhere(
|
@@ -1,7 +1,11 @@
|
|||||||
import { hasValidLicense } from '../../helpers/license.ee';
|
import { hasValidLicense } from '../../helpers/license.ee';
|
||||||
import Config from '../../models/config';
|
import Config from '../../models/config';
|
||||||
|
|
||||||
const getConfig = async (_parent, params) => {
|
type Params = {
|
||||||
|
keys: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getConfig = async (_parent: unknown, params: Params) => {
|
||||||
if (!(await hasValidLicense())) return {};
|
if (!(await hasValidLicense())) return {};
|
||||||
|
|
||||||
const configQuery = Config.query();
|
const configQuery = Config.query();
|
||||||
@@ -18,7 +22,7 @@ const getConfig = async (_parent, params) => {
|
|||||||
computedConfig[key] = value?.data;
|
computedConfig[key] = value?.data;
|
||||||
|
|
||||||
return computedConfig;
|
return computedConfig;
|
||||||
}, {});
|
}, {} as Record<string, unknown>);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getConfig;
|
export default getConfig;
|
@@ -1,15 +1,23 @@
|
|||||||
|
import { IConnection } from '@automatisch/types';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
import Connection from '../../models/connection';
|
import Connection from '../../models/connection';
|
||||||
|
|
||||||
const getConnectedApps = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getConnectedApps = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('read', 'Connection');
|
const conditions = context.currentUser.can('read', 'Connection');
|
||||||
|
|
||||||
const userConnections = context.currentUser.$relatedQuery('connections');
|
const userConnections = context.currentUser.$relatedQuery('connections');
|
||||||
const allConnections = Connection.query();
|
const allConnections = Connection.query();
|
||||||
const connectionBaseQuery = conditions.isCreator
|
const connectionBaseQuery = conditions.isCreator ? userConnections : allConnections;
|
||||||
? userConnections
|
|
||||||
: allConnections;
|
|
||||||
|
|
||||||
const userFlows = context.currentUser.$relatedQuery('flows');
|
const userFlows = context.currentUser.$relatedQuery('flows');
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
||||||
@@ -43,7 +51,7 @@ const getConnectedApps = async (_parent, params, context) => {
|
|||||||
})
|
})
|
||||||
.map((app) => {
|
.map((app) => {
|
||||||
const connection = connections.find(
|
const connection = connections.find(
|
||||||
(connection) => connection.key === app.key
|
(connection) => (connection as IConnection).key === app.key
|
||||||
);
|
);
|
||||||
|
|
||||||
app.connectionCount = connection?.count || 0;
|
app.connectionCount = connection?.count || 0;
|
@@ -1,5 +0,0 @@
|
|||||||
const getCurrentUser = async (_parent, _params, context) => {
|
|
||||||
return context.currentUser;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getCurrentUser;
|
|
11
packages/backend/src/graphql/queries/get-current-user.ts
Normal file
11
packages/backend/src/graphql/queries/get-current-user.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
|
|
||||||
|
const getCurrentUser = async (
|
||||||
|
_parent: unknown,
|
||||||
|
_params: unknown,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
|
return context.currentUser;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getCurrentUser;
|
@@ -1,10 +1,22 @@
|
|||||||
|
import { IDynamicData, IJSONObject } from '@automatisch/types';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Step from '../../models/step';
|
import Step from '../../models/step';
|
||||||
import ExecutionStep from '../../models/execution-step';
|
import ExecutionStep from '../../models/execution-step';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
import computeParameters from '../../helpers/compute-parameters';
|
import computeParameters from '../../helpers/compute-parameters';
|
||||||
|
|
||||||
const getDynamicData = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
stepId: string;
|
||||||
|
key: string;
|
||||||
|
parameters: IJSONObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDynamicData = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('update', 'Flow');
|
const conditions = context.currentUser.can('update', 'Flow');
|
||||||
const userSteps = context.currentUser.$relatedQuery('steps');
|
const userSteps = context.currentUser.$relatedQuery('steps');
|
||||||
const allSteps = Step.query();
|
const allSteps = Step.query();
|
||||||
@@ -28,7 +40,9 @@ const getDynamicData = async (_parent, params, context) => {
|
|||||||
const app = await App.findOneByKey(step.appKey);
|
const app = await App.findOneByKey(step.appKey);
|
||||||
const $ = await globalVariable({ connection, app, flow, step });
|
const $ = await globalVariable({ connection, app, flow, step });
|
||||||
|
|
||||||
const command = app.dynamicData.find((data) => data.key === params.key);
|
const command = app.dynamicData.find(
|
||||||
|
(data: IDynamicData) => data.key === params.key
|
||||||
|
);
|
||||||
|
|
||||||
// apply run-time parameters that're not persisted yet
|
// apply run-time parameters that're not persisted yet
|
||||||
for (const parameterKey in params.parameters) {
|
for (const parameterKey in params.parameters) {
|
||||||
@@ -39,17 +53,12 @@ const getDynamicData = async (_parent, params, context) => {
|
|||||||
const lastExecution = await flow.$relatedQuery('lastExecution');
|
const lastExecution = await flow.$relatedQuery('lastExecution');
|
||||||
const lastExecutionId = lastExecution?.id;
|
const lastExecutionId = lastExecution?.id;
|
||||||
|
|
||||||
const priorExecutionSteps = lastExecutionId
|
const priorExecutionSteps = lastExecutionId ? await ExecutionStep.query().where({
|
||||||
? await ExecutionStep.query().where({
|
execution_id: lastExecutionId,
|
||||||
execution_id: lastExecutionId,
|
}) : [];
|
||||||
})
|
|
||||||
: [];
|
|
||||||
|
|
||||||
// compute variables in parameters
|
// compute variables in parameters
|
||||||
const computedParameters = computeParameters(
|
const computedParameters = computeParameters($.step.parameters, priorExecutionSteps);
|
||||||
$.step.parameters,
|
|
||||||
priorExecutionSteps
|
|
||||||
);
|
|
||||||
|
|
||||||
$.step.parameters = computedParameters;
|
$.step.parameters = computedParameters;
|
||||||
|
|
@@ -1,8 +1,20 @@
|
|||||||
|
import { IDynamicFields, IJSONObject } from '@automatisch/types';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
import Step from '../../models/step';
|
import Step from '../../models/step';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
|
|
||||||
const getDynamicFields = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
stepId: string;
|
||||||
|
key: string;
|
||||||
|
parameters: IJSONObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDynamicFields = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('update', 'Flow');
|
const conditions = context.currentUser.can('update', 'Flow');
|
||||||
const userSteps = context.currentUser.$relatedQuery('steps');
|
const userSteps = context.currentUser.$relatedQuery('steps');
|
||||||
const allSteps = Step.query();
|
const allSteps = Step.query();
|
||||||
@@ -25,14 +37,16 @@ const getDynamicFields = async (_parent, params, context) => {
|
|||||||
const app = await App.findOneByKey(step.appKey);
|
const app = await App.findOneByKey(step.appKey);
|
||||||
const $ = await globalVariable({ connection, app, flow: step.flow, step });
|
const $ = await globalVariable({ connection, app, flow: step.flow, step });
|
||||||
|
|
||||||
const command = app.dynamicFields.find((data) => data.key === params.key);
|
const command = app.dynamicFields.find(
|
||||||
|
(data: IDynamicFields) => data.key === params.key
|
||||||
|
);
|
||||||
|
|
||||||
for (const parameterKey in params.parameters) {
|
for (const parameterKey in params.parameters) {
|
||||||
const parameterValue = params.parameters[parameterKey];
|
const parameterValue = params.parameters[parameterKey];
|
||||||
$.step.parameters[parameterKey] = parameterValue;
|
$.step.parameters[parameterKey] = parameterValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const additionalFields = (await command.run($)) || [];
|
const additionalFields = await command.run($) || [];
|
||||||
|
|
||||||
return additionalFields;
|
return additionalFields;
|
||||||
};
|
};
|
@@ -1,13 +1,22 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import paginate from '../../helpers/pagination';
|
import paginate from '../../helpers/pagination';
|
||||||
import Execution from '../../models/execution';
|
import Execution from '../../models/execution';
|
||||||
|
|
||||||
const getExecutionSteps = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
executionId: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExecutionSteps = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('read', 'Execution');
|
const conditions = context.currentUser.can('read', 'Execution');
|
||||||
const userExecutions = context.currentUser.$relatedQuery('executions');
|
const userExecutions = context.currentUser.$relatedQuery('executions');
|
||||||
const allExecutions = Execution.query();
|
const allExecutions = Execution.query();
|
||||||
const executionBaseQuery = conditions.isCreator
|
const executionBaseQuery = conditions.isCreator ? userExecutions : allExecutions;
|
||||||
? userExecutions
|
|
||||||
: allExecutions;
|
|
||||||
|
|
||||||
const execution = await executionBaseQuery
|
const execution = await executionBaseQuery
|
||||||
.clone()
|
.clone()
|
@@ -1,12 +1,19 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import Execution from '../../models/execution';
|
import Execution from '../../models/execution';
|
||||||
|
|
||||||
const getExecution = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
executionId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExecution = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('read', 'Execution');
|
const conditions = context.currentUser.can('read', 'Execution');
|
||||||
const userExecutions = context.currentUser.$relatedQuery('executions');
|
const userExecutions = context.currentUser.$relatedQuery('executions');
|
||||||
const allExecutions = Execution.query();
|
const allExecutions = Execution.query();
|
||||||
const executionBaseQuery = conditions.isCreator
|
const executionBaseQuery = conditions.isCreator ? userExecutions : allExecutions;
|
||||||
? userExecutions
|
|
||||||
: allExecutions;
|
|
||||||
|
|
||||||
const execution = await executionBaseQuery
|
const execution = await executionBaseQuery
|
||||||
.clone()
|
.clone()
|
@@ -1,18 +1,36 @@
|
|||||||
import { raw } from 'objection';
|
import { raw } from 'objection';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import Execution from '../../models/execution';
|
import Execution from '../../models/execution';
|
||||||
import paginate from '../../helpers/pagination';
|
import paginate from '../../helpers/pagination';
|
||||||
|
|
||||||
const getExecutions = async (_parent, params, context) => {
|
type Filters = {
|
||||||
|
flowId?: string;
|
||||||
|
status?: string;
|
||||||
|
createdAt?: {
|
||||||
|
from?: string;
|
||||||
|
to?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type Params = {
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
filters?: Filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExecutions = async (
|
||||||
|
_parent: unknown,
|
||||||
|
params: Params,
|
||||||
|
context: Context
|
||||||
|
) => {
|
||||||
const conditions = context.currentUser.can('read', 'Execution');
|
const conditions = context.currentUser.can('read', 'Execution');
|
||||||
|
|
||||||
const filters = params.filters;
|
const filters = params.filters;
|
||||||
|
|
||||||
const userExecutions = context.currentUser.$relatedQuery('executions');
|
const userExecutions = context.currentUser.$relatedQuery('executions');
|
||||||
const allExecutions = Execution.query();
|
const allExecutions = Execution.query();
|
||||||
const executionBaseQuery = conditions.isCreator
|
const executionBaseQuery = conditions.isCreator ? userExecutions : allExecutions;
|
||||||
? userExecutions
|
|
||||||
: allExecutions;
|
|
||||||
|
|
||||||
const selectStatusStatement = `
|
const selectStatusStatement = `
|
||||||
case
|
case
|
||||||
@@ -30,7 +48,8 @@ const getExecutions = async (_parent, params, context) => {
|
|||||||
.groupBy('executions.id')
|
.groupBy('executions.id')
|
||||||
.orderBy('created_at', 'desc');
|
.orderBy('created_at', 'desc');
|
||||||
|
|
||||||
const computedExecutions = Execution.query()
|
const computedExecutions = Execution
|
||||||
|
.query()
|
||||||
.with('executions', executions)
|
.with('executions', executions)
|
||||||
.withSoftDeleted()
|
.withSoftDeleted()
|
||||||
.withGraphFetched({
|
.withGraphFetched({
|
||||||
@@ -50,16 +69,20 @@ const getExecutions = async (_parent, params, context) => {
|
|||||||
if (filters?.createdAt) {
|
if (filters?.createdAt) {
|
||||||
const createdAtFilter = filters.createdAt;
|
const createdAtFilter = filters.createdAt;
|
||||||
if (createdAtFilter.from) {
|
if (createdAtFilter.from) {
|
||||||
const isoFromDateTime = DateTime.fromMillis(
|
const isoFromDateTime = DateTime
|
||||||
parseInt(createdAtFilter.from, 10)
|
.fromMillis(
|
||||||
).toISO();
|
parseInt(createdAtFilter.from, 10)
|
||||||
|
)
|
||||||
|
.toISO();
|
||||||
computedExecutions.where('executions.created_at', '>=', isoFromDateTime);
|
computedExecutions.where('executions.created_at', '>=', isoFromDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createdAtFilter.to) {
|
if (createdAtFilter.to) {
|
||||||
const isoToDateTime = DateTime.fromMillis(
|
const isoToDateTime = DateTime
|
||||||
parseInt(createdAtFilter.to, 10)
|
.fromMillis(
|
||||||
).toISO();
|
parseInt(createdAtFilter.to, 10)
|
||||||
|
)
|
||||||
|
.toISO();
|
||||||
computedExecutions.where('executions.created_at', '<=', isoToDateTime);
|
computedExecutions.where('executions.created_at', '<=', isoToDateTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,11 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
|
||||||
const getFlow = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFlow = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
const conditions = context.currentUser.can('read', 'Flow');
|
const conditions = context.currentUser.can('read', 'Flow');
|
||||||
const userFlows = context.currentUser.$relatedQuery('flows');
|
const userFlows = context.currentUser.$relatedQuery('flows');
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
@@ -1,7 +1,16 @@
|
|||||||
import Flow from '../../models/flow';
|
import Flow from '../../models/flow';
|
||||||
|
import Context from '../../types/express/context';
|
||||||
import paginate from '../../helpers/pagination';
|
import paginate from '../../helpers/pagination';
|
||||||
|
|
||||||
const getFlows = async (_parent, params, context) => {
|
type Params = {
|
||||||
|
appKey?: string;
|
||||||
|
connectionId?: string;
|
||||||
|
name?: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFlows = async (_parent: unknown, params: Params, context: Context) => {
|
||||||
const conditions = context.currentUser.can('read', 'Flow');
|
const conditions = context.currentUser.can('read', 'Flow');
|
||||||
const userFlows = context.currentUser.$relatedQuery('flows');
|
const userFlows = context.currentUser.$relatedQuery('flows');
|
||||||
const allFlows = Flow.query();
|
const allFlows = Flow.query();
|
@@ -1,9 +1,12 @@
|
|||||||
|
import Context from '../../types/express/context';
|
||||||
import Billing from '../../helpers/billing/index.ee';
|
import Billing from '../../helpers/billing/index.ee';
|
||||||
|
|
||||||
const getInvoices = async (_parent, _params, context) => {
|
const getInvoices = async (
|
||||||
const subscription = await context.currentUser.$relatedQuery(
|
_parent: unknown,
|
||||||
'currentSubscription'
|
_params: unknown,
|
||||||
);
|
context: Context
|
||||||
|
) => {
|
||||||
|
const subscription = await context.currentUser.$relatedQuery('currentSubscription');
|
||||||
|
|
||||||
if (!subscription) {
|
if (!subscription) {
|
||||||
return;
|
return;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user