Compare commits
1 Commits
hubspot-do
...
AUT-432
Author | SHA1 | Date | |
---|---|---|---|
![]() |
465dc8ba38 |
@@ -8,7 +8,7 @@
|
||||
"version": "latest"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": 18
|
||||
"version": 16
|
||||
},
|
||||
"ghcr.io/devcontainers/features/common-utils:1": {
|
||||
"username": "vscode",
|
||||
|
@@ -6,7 +6,8 @@
|
||||
"start": "lerna run --stream --parallel --scope=@*/{web,backend} dev",
|
||||
"start:web": "lerna run --stream --scope=@*/web dev",
|
||||
"start:backend": "lerna run --stream --scope=@*/backend dev",
|
||||
"lint": "lerna run --no-bail --stream --parallel --scope=@*/{web,backend} lint",
|
||||
"lint": "lerna run --no-bail --stream --parallel --scope=@*/{web,backend,cli} lint",
|
||||
"build:watch": "lerna run --no-bail --stream --parallel --scope=@*/{web,backend,cli} build:watch",
|
||||
"build:docs": "cd ./packages/docs && yarn install && yarn build"
|
||||
},
|
||||
"workspaces": {
|
||||
|
@@ -33,18 +33,19 @@
|
||||
"axios": "1.6.0",
|
||||
"bcrypt": "^5.0.1",
|
||||
"bullmq": "^3.0.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"cors": "^2.8.5",
|
||||
"crypto-js": "^4.1.1",
|
||||
"debug": "~2.6.9",
|
||||
"dotenv": "^10.0.0",
|
||||
"express": "~4.18.2",
|
||||
"express-async-handler": "^1.2.0",
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"express-graphql": "^0.12.0",
|
||||
"fast-xml-parser": "^4.0.11",
|
||||
"graphql-middleware": "^6.1.15",
|
||||
"graphql-shield": "^7.5.0",
|
||||
"graphql-tools": "^8.2.0",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"handlebars": "^4.7.7",
|
||||
"http-errors": "~1.6.3",
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
@@ -67,6 +68,7 @@
|
||||
"pluralize": "^8.0.0",
|
||||
"raw-body": "^2.5.2",
|
||||
"showdown": "^2.1.0",
|
||||
"stripe": "^11.13.0",
|
||||
"winston": "^3.7.1",
|
||||
"xmlrpc": "^1.3.2"
|
||||
},
|
||||
@@ -95,7 +97,6 @@
|
||||
"url": "https://github.com/automatisch/automatisch/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/utils": "^7.0.2",
|
||||
"nodemon": "^2.0.13",
|
||||
"supertest": "^6.3.3",
|
||||
"vitest": "^1.1.3"
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import defineAction from '../../../../helpers/define-action.js';
|
||||
|
||||
import base64ToString from './transformers/base64-to-string.js';
|
||||
import capitalize from './transformers/capitalize.js';
|
||||
import extractEmailAddress from './transformers/extract-email-address.js';
|
||||
import extractNumber from './transformers/extract-number.js';
|
||||
@@ -9,12 +8,10 @@ import lowercase from './transformers/lowercase.js';
|
||||
import markdownToHtml from './transformers/markdown-to-html.js';
|
||||
import pluralize from './transformers/pluralize.js';
|
||||
import replace from './transformers/replace.js';
|
||||
import stringToBase64 from './transformers/string-to-base64.js';
|
||||
import trimWhitespace from './transformers/trim-whitespace.js';
|
||||
import useDefaultValue from './transformers/use-default-value.js';
|
||||
|
||||
const transformers = {
|
||||
base64ToString,
|
||||
capitalize,
|
||||
extractEmailAddress,
|
||||
extractNumber,
|
||||
@@ -23,7 +20,6 @@ const transformers = {
|
||||
markdownToHtml,
|
||||
pluralize,
|
||||
replace,
|
||||
stringToBase64,
|
||||
trimWhitespace,
|
||||
useDefaultValue,
|
||||
};
|
||||
@@ -41,7 +37,6 @@ export default defineAction({
|
||||
required: true,
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Base64 to String', value: 'base64ToString' },
|
||||
{ label: 'Capitalize', value: 'capitalize' },
|
||||
{ label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' },
|
||||
{ label: 'Convert Markdown to HTML', value: 'markdownToHtml' },
|
||||
@@ -50,7 +45,6 @@ export default defineAction({
|
||||
{ label: 'Lowercase', value: 'lowercase' },
|
||||
{ label: 'Pluralize', value: 'pluralize' },
|
||||
{ label: 'Replace', value: 'replace' },
|
||||
{ label: 'String to Base64', value: 'stringToBase64' },
|
||||
{ label: 'Trim Whitespace', value: 'trimWhitespace' },
|
||||
{ label: 'Use Default Value', value: 'useDefaultValue' },
|
||||
],
|
||||
|
@@ -1,8 +0,0 @@
|
||||
const base64ToString = ($) => {
|
||||
const input = $.step.parameters.input;
|
||||
const decodedString = Buffer.from(input, 'base64').toString('utf8');
|
||||
|
||||
return decodedString;
|
||||
};
|
||||
|
||||
export default base64ToString;
|
@@ -1,8 +0,0 @@
|
||||
const stringtoBase64 = ($) => {
|
||||
const input = $.step.parameters.input;
|
||||
const base64String = Buffer.from(input).toString('base64');
|
||||
|
||||
return base64String;
|
||||
};
|
||||
|
||||
export default stringtoBase64;
|
@@ -1,4 +1,3 @@
|
||||
import base64ToString from './text/base64-to-string.js';
|
||||
import capitalize from './text/capitalize.js';
|
||||
import extractEmailAddress from './text/extract-email-address.js';
|
||||
import extractNumber from './text/extract-number.js';
|
||||
@@ -7,7 +6,6 @@ import lowercase from './text/lowercase.js';
|
||||
import markdownToHtml from './text/markdown-to-html.js';
|
||||
import pluralize from './text/pluralize.js';
|
||||
import replace from './text/replace.js';
|
||||
import stringToBase64 from './text/string-to-base64.js';
|
||||
import trimWhitespace from './text/trim-whitespace.js';
|
||||
import useDefaultValue from './text/use-default-value.js';
|
||||
import performMathOperation from './numbers/perform-math-operation.js';
|
||||
@@ -17,7 +15,6 @@ import formatPhoneNumber from './numbers/format-phone-number.js';
|
||||
import formatDateTime from './date-time/format-date-time.js';
|
||||
|
||||
const options = {
|
||||
base64ToString,
|
||||
capitalize,
|
||||
extractEmailAddress,
|
||||
extractNumber,
|
||||
@@ -26,7 +23,6 @@ const options = {
|
||||
markdownToHtml,
|
||||
pluralize,
|
||||
replace,
|
||||
stringToBase64,
|
||||
trimWhitespace,
|
||||
useDefaultValue,
|
||||
performMathOperation,
|
||||
|
@@ -1,12 +0,0 @@
|
||||
const base64ToString = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Text that will be converted from Base64 to string.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default base64ToString;
|
@@ -1,12 +0,0 @@
|
||||
const stringToBase64 = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Text that will be converted to Base64.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default stringToBase64;
|
@@ -1,5 +1,11 @@
|
||||
import createDatabaseItem from './create-database-item/index.js';
|
||||
import createPage from './create-page/index.js';
|
||||
import findDatabaseItem from './find-database-item/index.js';
|
||||
import updateDatabaseItem from './update-database-item/index.js';
|
||||
|
||||
export default [createDatabaseItem, createPage, findDatabaseItem];
|
||||
export default [
|
||||
createDatabaseItem,
|
||||
createPage,
|
||||
findDatabaseItem,
|
||||
updateDatabaseItem,
|
||||
];
|
||||
|
@@ -0,0 +1,157 @@
|
||||
import defineAction from '../../../../helpers/define-action.js';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Update database item',
|
||||
key: 'updateDatabaseItem',
|
||||
description: 'Updates a database item.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Database',
|
||||
key: 'databaseId',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listDatabases',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Item',
|
||||
key: 'itemId',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
variables: true,
|
||||
dependsOn: ['parameters.databaseId'],
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listDatabaseItems',
|
||||
},
|
||||
{
|
||||
name: 'parameters.databaseId',
|
||||
value: '{parameters.databaseId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Name',
|
||||
key: 'name',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description:
|
||||
'This field has a 2000 character limit. Any characters beyond 2000 will not be included.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Tags',
|
||||
key: 'tags',
|
||||
type: 'dynamic',
|
||||
required: false,
|
||||
description: '',
|
||||
fields: [
|
||||
{
|
||||
label: 'Tag',
|
||||
key: 'tag',
|
||||
type: 'dropdown',
|
||||
required: true,
|
||||
variables: true,
|
||||
dependsOn: ['parameters.databaseId'],
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listTags',
|
||||
},
|
||||
{
|
||||
name: 'parameters.databaseId',
|
||||
value: '{parameters.databaseId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Content',
|
||||
key: 'content',
|
||||
type: 'string',
|
||||
required: false,
|
||||
description:
|
||||
'You can choose to add extra text to the database item, with a limit of up to 2000 characters if desired.',
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const itemId = $.step.parameters.itemId;
|
||||
const name = $.step.parameters.name;
|
||||
const truncatedName = name.slice(0, 2000);
|
||||
const content = $.step.parameters.content;
|
||||
const truncatedContent = content.slice(0, 2000);
|
||||
const tags = $.step.parameters.tags;
|
||||
const formattedTags = tags
|
||||
.filter((tag) => tag.tag !== '')
|
||||
.map((tag) => tag.tag);
|
||||
|
||||
const body = {
|
||||
properties: {},
|
||||
};
|
||||
|
||||
if (truncatedName) {
|
||||
body.properties.Name = {
|
||||
title: [
|
||||
{
|
||||
text: {
|
||||
content: truncatedName,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (formattedTags?.length) {
|
||||
body.properties.Tags = {
|
||||
multi_select: formattedTags.map((tag) => ({ name: tag })),
|
||||
};
|
||||
}
|
||||
|
||||
if (truncatedContent) {
|
||||
const response = await $.http.get(`/v1/blocks/${itemId}/children`);
|
||||
const firstBlockId = response.data.results[0].id;
|
||||
|
||||
const body = {
|
||||
paragraph: {
|
||||
rich_text: [
|
||||
{
|
||||
type: 'text',
|
||||
text: {
|
||||
content: truncatedContent,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
await $.http.patch(`/v1/blocks/${firstBlockId}`, body);
|
||||
}
|
||||
|
||||
const { data } = await $.http.patch(`/v1/pages/${itemId}`, body);
|
||||
|
||||
$.setActionItem({
|
||||
raw: data,
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,4 +1,6 @@
|
||||
import listDatabaseItems from './list-database-items/index.js';
|
||||
import listDatabases from './list-databases/index.js';
|
||||
import listParentPages from './list-parent-pages/index.js';
|
||||
import listTags from './list-tags/index.js';
|
||||
|
||||
export default [listDatabases, listParentPages];
|
||||
export default [listDatabaseItems, listDatabases, listParentPages, listTags];
|
||||
|
@@ -0,0 +1,38 @@
|
||||
export default {
|
||||
name: 'List database items',
|
||||
key: 'listDatabaseItems',
|
||||
|
||||
async run($) {
|
||||
const databases = {
|
||||
data: [],
|
||||
error: null,
|
||||
};
|
||||
const payload = {
|
||||
start_cursor: undefined,
|
||||
};
|
||||
const databaseId = $.step.parameters.databaseId;
|
||||
|
||||
if (!databaseId) {
|
||||
return databases;
|
||||
}
|
||||
|
||||
do {
|
||||
const response = await $.http.post(
|
||||
`/v1/databases/${databaseId}/query`,
|
||||
payload
|
||||
);
|
||||
|
||||
payload.start_cursor = response.data.next_cursor;
|
||||
|
||||
for (const database of response.data.results) {
|
||||
databases.data.push({
|
||||
value: database.id,
|
||||
name:
|
||||
database.properties.Name?.title?.[0]?.plain_text || 'Untitled Page',
|
||||
});
|
||||
}
|
||||
} while (payload.start_cursor);
|
||||
|
||||
return databases;
|
||||
},
|
||||
};
|
@@ -22,7 +22,7 @@ export default {
|
||||
for (const database of response.data.results) {
|
||||
databases.data.push({
|
||||
value: database.id,
|
||||
name: database.title[0].plain_text,
|
||||
name: database.title?.[0]?.plain_text || 'Untitled Database',
|
||||
});
|
||||
}
|
||||
} while (payload.start_cursor);
|
||||
|
@@ -0,0 +1,38 @@
|
||||
export default {
|
||||
name: 'List tags',
|
||||
key: 'listTags',
|
||||
|
||||
async run($) {
|
||||
const tags = {
|
||||
data: [],
|
||||
error: null,
|
||||
};
|
||||
const databaseId = $.step.parameters.databaseId;
|
||||
let allTags;
|
||||
|
||||
if (!databaseId) {
|
||||
return tags;
|
||||
}
|
||||
|
||||
const response = await $.http.get(`/v1/databases/${databaseId}`);
|
||||
const tagsExist =
|
||||
response.data.properties.Tags.multi_select.options.length !== 0;
|
||||
|
||||
if (tagsExist) {
|
||||
allTags = response.data.properties.Tags.multi_select.options.map(
|
||||
(tag) => tag.name
|
||||
);
|
||||
} else {
|
||||
return tags;
|
||||
}
|
||||
|
||||
for (const tag of allTags) {
|
||||
tags.data.push({
|
||||
value: tag,
|
||||
name: tag,
|
||||
});
|
||||
}
|
||||
|
||||
return tags;
|
||||
},
|
||||
};
|
@@ -18,9 +18,7 @@ const port = process.env.PORT || '3000';
|
||||
const serveWebAppSeparately =
|
||||
process.env.SERVE_WEB_APP_SEPARATELY === 'true' ? true : false;
|
||||
|
||||
let apiUrl = new URL(
|
||||
process.env.API_URL || `${protocol}://${host}:${port}`
|
||||
).toString();
|
||||
let apiUrl = new URL(`${protocol}://${host}:${port}`).toString();
|
||||
apiUrl = apiUrl.substring(0, apiUrl.length - 1);
|
||||
|
||||
// use apiUrl by default, which has less priority over the following cases
|
||||
@@ -90,10 +88,6 @@ const appConfig = {
|
||||
licenseKey: process.env.LICENSE_KEY,
|
||||
sentryDsn: process.env.SENTRY_DSN,
|
||||
CI: process.env.CI === 'true',
|
||||
disableNotificationsPage: process.env.DISABLE_NOTIFICATIONS_PAGE === 'true',
|
||||
disableFavicon: process.env.DISABLE_FAVICON === 'true',
|
||||
additionalDrawerLink: process.env.ADDITIONAL_DRAWER_LINK,
|
||||
additionalDrawerLinkText: process.env.ADDITIONAL_DRAWER_LINK_TEXT,
|
||||
};
|
||||
|
||||
if (!appConfig.encryptionKey) {
|
||||
|
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import AppAuthClient from '../../../../../models/app-auth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const appAuthClient = await AppAuthClient.query()
|
||||
.findById(request.params.appAuthClientId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, appAuthClient);
|
||||
};
|
@@ -1,52 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import getAdminAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/get-app-auth-client.js';
|
||||
import { createAppAuthClient } from '../../../../../../test/factories/app-auth-client.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/app-auth-clients/:appAuthClientId', () => {
|
||||
let currentUser, currentUserRole, currentAppAuthClient, token;
|
||||
|
||||
describe('with valid license key', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
currentUserRole = await createRole({ key: 'admin' });
|
||||
currentUser = await createUser({ roleId: currentUserRole.id });
|
||||
currentAppAuthClient = await createAppAuthClient();
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified app auth client info', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/app-auth-clients/${currentAppAuthClient.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAdminAppAuthClientMock(currentAppAuthClient);
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing app auth client UUID', async () => {
|
||||
const notExistingAppAuthClientUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/admin/app-auth-clients/${notExistingAppAuthClientUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/admin/app-auth-clients/invalidAppAuthClientUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,6 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import permissionCatalog from '../../../../../helpers/permission-catalog.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
renderObject(response, permissionCatalog);
|
||||
};
|
@@ -1,32 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import getPermissionsCatalogMock from '../../../../../../test/mocks/rest/api/v1/admin/permissions/get-permissions-catalog.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/permissions/catalog', () => {
|
||||
let role, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
role = await createRole({ key: 'admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return roles', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/permissions/catalog')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getPermissionsCatalogMock();
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,16 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const role = await Role.query()
|
||||
.leftJoinRelated({
|
||||
permissions: true,
|
||||
})
|
||||
.withGraphFetched({
|
||||
permissions: true,
|
||||
})
|
||||
.findById(request.params.roleId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, role);
|
||||
};
|
@@ -1,59 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createPermission } from '../../../../../../test/factories/permission.js';
|
||||
import getRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/get-role.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/roles/:roleId', () => {
|
||||
let role, currentUser, token, permissionOne, permissionTwo;
|
||||
|
||||
beforeEach(async () => {
|
||||
role = await createRole({ key: 'admin' });
|
||||
permissionOne = await createPermission({ roleId: role.id });
|
||||
permissionTwo = await createPermission({ roleId: role.id });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return role', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/roles/${role.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getRoleMock(role, [
|
||||
permissionOne,
|
||||
permissionTwo,
|
||||
]);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing role UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingRoleUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/admin/roles/${notExistingRoleUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/roles/invalidRoleUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
@@ -1,8 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const roles = await Role.query().orderBy('name');
|
||||
|
||||
renderObject(response, roles);
|
||||
};
|
@@ -1,33 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import getRolesMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/get-roles.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/roles', () => {
|
||||
let roleOne, roleTwo, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
roleOne = await createRole({ key: 'admin' });
|
||||
roleTwo = await createRole({ key: 'user' });
|
||||
currentUser = await createUser({ roleId: roleOne.id });
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return roles', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/roles')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getRolesMock([roleOne, roleTwo]);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProvider = await SamlAuthProvider.query()
|
||||
.findById(request.params.samlAuthProviderId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, samlAuthProvider);
|
||||
};
|
@@ -1,57 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import getSamlAuthProviderMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/get-saml-auth-provider.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/saml-auth-provider/:samlAuthProviderId', () => {
|
||||
let samlAuthProvider, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole({ key: 'admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
samlAuthProvider = await createSamlAuthProvider();
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return saml auth provider with specified id', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getSamlAuthProviderMock(samlAuthProvider);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing saml auth provider UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingSamlAuthProviderUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(
|
||||
`/api/v1/admin/saml-auth-providers/${notExistingSamlAuthProviderUUID}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/saml-auth-providers/invalidSamlAuthProviderUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProviders = await SamlAuthProvider.query().orderBy(
|
||||
'created_at',
|
||||
'desc'
|
||||
);
|
||||
|
||||
renderObject(response, samlAuthProviders);
|
||||
};
|
@@ -1,39 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import getSamlAuthProvidersMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/get-saml-auth-providers.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/saml-auth-providers', () => {
|
||||
let samlAuthProviderOne, samlAuthProviderTwo, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole({ key: 'admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
samlAuthProviderOne = await createSamlAuthProvider();
|
||||
samlAuthProviderTwo = await createSamlAuthProvider();
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return saml auth providers', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/saml-auth-providers')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getSamlAuthProvidersMock([
|
||||
samlAuthProviderTwo,
|
||||
samlAuthProviderOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,13 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const user = await User.query()
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
})
|
||||
.findById(request.params.userId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, user);
|
||||
};
|
@@ -1,55 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../../test/factories/user';
|
||||
import { createRole } from '../../../../../../test/factories/role';
|
||||
import getUserMock from '../../../../../../test/mocks/rest/api/v1/admin/users/get-user.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/users/:userId', () => {
|
||||
let currentUser, currentUserRole, anotherUser, anotherUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ key: 'admin' });
|
||||
currentUser = await createUser({ roleId: currentUserRole.id });
|
||||
|
||||
anotherUser = await createUser();
|
||||
anotherUserRole = await anotherUser.$relatedQuery('role');
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified user info', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/users/${anotherUser.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getUserMock(anotherUser, anotherUserRole);
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing user UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingUserUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/admin/users/${notExistingUserUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/users/invalidUserUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
@@ -1,15 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
import paginateRest from '../../../../../helpers/pagination-rest.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const usersQuery = User.query()
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
})
|
||||
.orderBy('full_name', 'asc');
|
||||
|
||||
const users = await paginateRest(usersQuery, request.query.page);
|
||||
|
||||
renderObject(response, users);
|
||||
};
|
@@ -1,49 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createRole } from '../../../../../../test/factories/role';
|
||||
import { createUser } from '../../../../../../test/factories/user';
|
||||
import getUsersMock from '../../../../../../test/mocks/rest/api/v1/admin/users/get-users.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/users', () => {
|
||||
let currentUser, currentUserRole, anotherUser, anotherUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ key: 'admin' });
|
||||
|
||||
currentUser = await createUser({
|
||||
roleId: currentUserRole.id,
|
||||
fullName: 'Current User',
|
||||
});
|
||||
|
||||
anotherUserRole = await createRole({
|
||||
key: 'anotherUser',
|
||||
name: 'Another user role',
|
||||
});
|
||||
|
||||
anotherUser = await createUser({
|
||||
roleId: anotherUserRole.id,
|
||||
fullName: 'Another User',
|
||||
});
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return users data', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = await getUsersMock(
|
||||
[anotherUser, currentUser],
|
||||
[anotherUserRole, currentUserRole]
|
||||
);
|
||||
|
||||
expect(response.body).toEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import AppAuthClient from '../../../../models/app-auth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const appAuthClient = await AppAuthClient.query()
|
||||
.findById(request.params.appAuthClientId)
|
||||
.where({ active: true })
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, appAuthClient);
|
||||
};
|
@@ -1,48 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getAppAuthClientMock from '../../../../../test/mocks/rest/api/v1/admin/get-app-auth-client.js';
|
||||
import { createAppAuthClient } from '../../../../../test/factories/app-auth-client.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/app-auth-clients/:id', () => {
|
||||
let currentUser, currentAppAuthClient, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
currentUser = await createUser();
|
||||
currentAppAuthClient = await createAppAuthClient();
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified app auth client info', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/app-auth-clients/${currentAppAuthClient.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppAuthClientMock(currentAppAuthClient);
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing app auth client ID', async () => {
|
||||
const notExistingAppAuthClientUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/app-auth-clients/${notExistingAppAuthClientUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/app-auth-clients/invalidAppAuthClientUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
@@ -1,8 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const app = await App.findOneByKey(request.params.appKey);
|
||||
|
||||
renderObject(response, app, { serializer: 'App' });
|
||||
};
|
@@ -1,35 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getAppMock from '../../../../../test/mocks/rest/api/v1/apps/get-app.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the app info', async () => {
|
||||
const exampleApp = await App.findOneByKey('github');
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${exampleApp.key}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppMock(exampleApp);
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
@@ -1,13 +0,0 @@
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import { hasValidLicense } from '../../../../helpers/license.ee.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const info = {
|
||||
isCloud: appConfig.isCloud,
|
||||
isMation: appConfig.isMation,
|
||||
isEnterprise: await hasValidLicense(),
|
||||
};
|
||||
|
||||
renderObject(response, info);
|
||||
};
|
@@ -1,22 +0,0 @@
|
||||
import { vi, expect, describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import app from '../../../../app.js';
|
||||
import infoMock from '../../../../../test/mocks/rest/api/v1/automatisch/info.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/info', () => {
|
||||
it('should return Automatisch info', async () => {
|
||||
vi.spyOn(appConfig, 'isCloud', 'get').mockReturnValue(false);
|
||||
vi.spyOn(appConfig, 'isMation', 'get').mockReturnValue(false);
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/info')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = infoMock();
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,15 +0,0 @@
|
||||
import { getLicense } from '../../../../helpers/license.ee.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const license = await getLicense();
|
||||
|
||||
const computedLicense = {
|
||||
id: license ? license.id : null,
|
||||
name: license ? license.name : null,
|
||||
expireAt: license ? license.expireAt : null,
|
||||
verified: license ? true : false,
|
||||
};
|
||||
|
||||
renderObject(response, computedLicense);
|
||||
};
|
@@ -1,23 +0,0 @@
|
||||
import { vi, expect, describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import licenseMock from '../../../../../test/mocks/rest/api/v1/automatisch/license.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/license', () => {
|
||||
it('should return Automatisch license info', async () => {
|
||||
vi.spyOn(license, 'getLicense').mockResolvedValue({
|
||||
id: '123',
|
||||
name: 'license-name',
|
||||
expireAt: '2025-12-31T23:59:59Z',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/license')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = licenseMock();
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,19 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import axios from '../../../../helpers/axios-with-proxy.js';
|
||||
import logger from '../../../../helpers/logger.js';
|
||||
|
||||
const NOTIFICATIONS_URL =
|
||||
'https://notifications.automatisch.io/notifications.json';
|
||||
|
||||
export default async (request, response) => {
|
||||
let notifications = [];
|
||||
|
||||
try {
|
||||
const response = await axios.get(NOTIFICATIONS_URL);
|
||||
notifications = response.data;
|
||||
} catch (error) {
|
||||
logger.error('Error fetching notifications API endpoint!', error);
|
||||
}
|
||||
|
||||
renderObject(response, notifications);
|
||||
};
|
@@ -1,9 +0,0 @@
|
||||
import { describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/notifications', () => {
|
||||
it('should return Automatisch notifications', async () => {
|
||||
await request(app).get('/api/v1/automatisch/notifications').expect(200);
|
||||
});
|
||||
});
|
@@ -1,6 +0,0 @@
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
renderObject(response, { version: appConfig.version });
|
||||
};
|
@@ -1,26 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/version', () => {
|
||||
it('should return Automatisch version', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/version')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = {
|
||||
data: {
|
||||
version: '0.10.0',
|
||||
},
|
||||
meta: {
|
||||
count: 1,
|
||||
currentPage: null,
|
||||
isArray: false,
|
||||
totalPages: null,
|
||||
type: 'Object',
|
||||
},
|
||||
};
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const flow = await request.currentUser.authorizedFlows
|
||||
.withGraphJoined({ steps: true })
|
||||
.orderBy('steps.position', 'asc')
|
||||
.findOne({ 'flows.id': request.params.flowId })
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, flow);
|
||||
};
|
@@ -1,102 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import { createFlow } from '../../../../../test/factories/flow';
|
||||
import { createStep } from '../../../../../test/factories/step';
|
||||
import { createPermission } from '../../../../../test/factories/permission';
|
||||
import getFlowMock from '../../../../../test/mocks/rest/api/v1/flows/get-flow';
|
||||
|
||||
describe('GET /api/v1/flows/:flowId', () => {
|
||||
let currentUser, currentUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
currentUserRole = await currentUser.$relatedQuery('role');
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the flow data of current user', async () => {
|
||||
const currentUserflow = await createFlow({ userId: currentUser.id });
|
||||
const triggerStep = await createStep({ flowId: currentUserflow.id });
|
||||
const actionStep = await createStep({ flowId: currentUserflow.id });
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: ['isCreator'],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/flows/${currentUserflow.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getFlowMock(currentUserflow, [
|
||||
triggerStep,
|
||||
actionStep,
|
||||
]);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return the flow data of another user', async () => {
|
||||
const anotherUser = await createUser();
|
||||
const anotherUserFlow = await createFlow({ userId: anotherUser.id });
|
||||
const triggerStep = await createStep({ flowId: anotherUserFlow.id });
|
||||
const actionStep = await createStep({ flowId: anotherUserFlow.id });
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: [],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/flows/${anotherUserFlow.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getFlowMock(anotherUserFlow, [
|
||||
triggerStep,
|
||||
actionStep,
|
||||
]);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing flow UUID', async () => {
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: [],
|
||||
});
|
||||
|
||||
const notExistingFlowUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/flows/${notExistingFlowUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: [],
|
||||
});
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/flows/invalidFlowUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
@@ -1,8 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import Billing from '../../../../helpers/billing/index.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const paddleInfo = Billing.paddleInfo;
|
||||
|
||||
renderObject(response, paddleInfo);
|
||||
};
|
@@ -1,33 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getPaddleInfoMock from '../../../../../test/mocks/rest/api/v1/payment/get-paddle-info.js';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import billing from '../../../../helpers/billing/index.ee.js';
|
||||
|
||||
describe('GET /api/v1/payment/paddle-info', () => {
|
||||
let user, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await createUser();
|
||||
token = createAuthTokenByUserId(user.id);
|
||||
|
||||
vi.spyOn(appConfig, 'isCloud', 'get').mockReturnValue(true);
|
||||
vi.spyOn(billing.paddleInfo, 'vendorId', 'get').mockReturnValue(
|
||||
'sampleVendorId'
|
||||
);
|
||||
});
|
||||
|
||||
it('should return payment plans', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/payment/paddle-info')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = await getPaddleInfoMock();
|
||||
|
||||
expect(response.body).toEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
@@ -1,8 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import Billing from '../../../../helpers/billing/index.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const paymentPlans = Billing.paddlePlans;
|
||||
|
||||
renderObject(response, paymentPlans);
|
||||
};
|
@@ -1,29 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getPaymentPlansMock from '../../../../../test/mocks/rest/api/v1/payment/get-plans.js';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
|
||||
describe('GET /api/v1/payment/plans', () => {
|
||||
let user, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await createUser();
|
||||
token = createAuthTokenByUserId(user.id);
|
||||
|
||||
vi.spyOn(appConfig, 'isCloud', 'get').mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('should return payment plans', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/payment/plans')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = await getPaymentPlansMock();
|
||||
|
||||
expect(response.body).toEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
@@ -1,5 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
renderObject(response, request.currentUser);
|
||||
};
|
@@ -1,26 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getCurrentUserMock from '../../../../../test/mocks/rest/api/v1/users/get-current-user';
|
||||
|
||||
describe('GET /api/v1/users/me', () => {
|
||||
let role, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
role = await currentUser.$relatedQuery('role');
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return current user info', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/users/me')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getCurrentUserMock(currentUser, role);
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,7 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const invoices = await request.currentUser.getInvoices();
|
||||
|
||||
renderObject(response, invoices);
|
||||
};
|
@@ -1,34 +0,0 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import User from '../../../../models/user';
|
||||
import getInvoicesMock from '../../../../../test/mocks/rest/api/v1/users/get-invoices.ee';
|
||||
|
||||
describe('GET /api/v1/user/invoices', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return current user invoices', async () => {
|
||||
const invoices = [
|
||||
{ id: 1, amount: 100, description: 'Invoice 1' },
|
||||
{ id: 2, amount: 200, description: 'Invoice 2' },
|
||||
];
|
||||
|
||||
vi.spyOn(User.prototype, 'getInvoices').mockResolvedValue(invoices);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/users/invoices')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getInvoicesMock(invoices);
|
||||
|
||||
expect(response.body).toEqual(expectedPayload);
|
||||
});
|
||||
});
|
@@ -1,12 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const inTrial = await request.currentUser.inTrial();
|
||||
|
||||
const trialInfo = {
|
||||
inTrial,
|
||||
expireAt: request.currentUser.trialExpiryDate,
|
||||
};
|
||||
|
||||
renderObject(response, trialInfo);
|
||||
};
|
@@ -1,38 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getUserTrialMock from '../../../../../test/mocks/rest/api/v1/users/get-user-trial.js';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import { DateTime } from 'luxon';
|
||||
import User from '../../../../models/user.js';
|
||||
|
||||
describe('GET /api/v1/users/:userId/trial', () => {
|
||||
let user, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const trialExpiryDate = DateTime.now().plus({ days: 30 }).toISODate();
|
||||
user = await createUser({ trialExpiryDate });
|
||||
token = createAuthTokenByUserId(user.id);
|
||||
|
||||
vi.spyOn(appConfig, 'isCloud', 'get').mockReturnValue(true);
|
||||
});
|
||||
|
||||
describe('should return in trial, active subscription and expire at info', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(User.prototype, 'inTrial').mockResolvedValue(false);
|
||||
vi.spyOn(User.prototype, 'hasActiveSubscription').mockResolvedValue(true);
|
||||
});
|
||||
|
||||
it('should return null', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/users/${user.id}/trial`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = await getUserTrialMock(user);
|
||||
expect(response.body).toEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,3 +0,0 @@
|
||||
export default async (request, response) => {
|
||||
response.status(200).end();
|
||||
};
|
@@ -1,9 +0,0 @@
|
||||
import { describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../app.js';
|
||||
|
||||
describe('GET /healthcheck', () => {
|
||||
it('should return 200 response with version data', async () => {
|
||||
await request(app).get('/healthcheck').expect(200);
|
||||
});
|
||||
});
|
@@ -1,13 +1,8 @@
|
||||
import Step from '../../models/flow.js';
|
||||
|
||||
const deleteStep = async (_parent, params, context) => {
|
||||
const conditions = context.currentUser.can('update', 'Flow');
|
||||
const isCreator = conditions.isCreator;
|
||||
const allSteps = Step.query();
|
||||
const userSteps = context.currentUser.$relatedQuery('steps');
|
||||
const baseQuery = isCreator ? userSteps : allSteps;
|
||||
context.currentUser.can('update', 'Flow');
|
||||
|
||||
const step = await baseQuery
|
||||
const step = await context.currentUser
|
||||
.$relatedQuery('steps')
|
||||
.withGraphFetched('flow')
|
||||
.findOne({
|
||||
'steps.id': params.input.id,
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import appConfig from '../../config/app.js';
|
||||
import User from '../../models/user.js';
|
||||
import Role from '../../models/role.js';
|
||||
|
||||
const registerUser = async (_parent, params) => {
|
||||
if (!appConfig.isCloud) return;
|
||||
|
||||
const { fullName, email, password } = params.input;
|
||||
|
||||
const existingUser = await User.query().findOne({
|
||||
|
@@ -1,17 +1,9 @@
|
||||
import appConfig from '../../config/app.js';
|
||||
import { hasValidLicense } from '../../helpers/license.ee.js';
|
||||
import Config from '../../models/config.js';
|
||||
|
||||
const getConfig = async (_parent, params) => {
|
||||
if (!(await hasValidLicense())) return {};
|
||||
|
||||
const defaultConfig = {
|
||||
disableNotificationsPage: appConfig.disableNotificationsPage,
|
||||
disableFavicon: appConfig.disableFavicon,
|
||||
additionalDrawerLink: appConfig.additionalDrawerLink,
|
||||
additionalDrawerLinkText: appConfig.additionalDrawerLinkText,
|
||||
};
|
||||
|
||||
const configQuery = Config.query();
|
||||
|
||||
if (Array.isArray(params.keys)) {
|
||||
@@ -26,7 +18,7 @@ const getConfig = async (_parent, params) => {
|
||||
computedConfig[key] = value?.data;
|
||||
|
||||
return computedConfig;
|
||||
}, defaultConfig);
|
||||
}, {});
|
||||
};
|
||||
|
||||
export default getConfig;
|
||||
|
@@ -2,7 +2,6 @@ import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../app';
|
||||
import { createConfig } from '../../../test/factories/config';
|
||||
import appConfig from '../../config/app';
|
||||
import * as license from '../../helpers/license.ee';
|
||||
|
||||
describe('graphQL getConfig query', () => {
|
||||
@@ -57,10 +56,6 @@ describe('graphQL getConfig query', () => {
|
||||
[configOne.key]: configOne.value.data,
|
||||
[configTwo.key]: configTwo.value.data,
|
||||
[configThree.key]: configThree.value.data,
|
||||
disableNotificationsPage: false,
|
||||
disableFavicon: false,
|
||||
additionalDrawerLink: undefined,
|
||||
additionalDrawerLinkText: undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -87,48 +82,6 @@ describe('graphQL getConfig query', () => {
|
||||
getConfig: {
|
||||
[configOne.key]: configOne.value.data,
|
||||
[configTwo.key]: configTwo.value.data,
|
||||
disableNotificationsPage: false,
|
||||
disableFavicon: false,
|
||||
additionalDrawerLink: undefined,
|
||||
additionalDrawerLinkText: undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(response.body).toEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and with different defaults', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(appConfig, 'disableNotificationsPage', 'get').mockReturnValue(
|
||||
true
|
||||
);
|
||||
vi.spyOn(appConfig, 'disableFavicon', 'get').mockReturnValue(true);
|
||||
vi.spyOn(appConfig, 'additionalDrawerLink', 'get').mockReturnValue(
|
||||
'https://automatisch.io'
|
||||
);
|
||||
vi.spyOn(appConfig, 'additionalDrawerLinkText', 'get').mockReturnValue(
|
||||
'Automatisch'
|
||||
);
|
||||
});
|
||||
|
||||
it('should return custom config', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = {
|
||||
data: {
|
||||
getConfig: {
|
||||
[configOne.key]: configOne.value.data,
|
||||
[configTwo.key]: configTwo.value.data,
|
||||
[configThree.key]: configThree.value.data,
|
||||
disableNotificationsPage: true,
|
||||
disableFavicon: true,
|
||||
additionalDrawerLink: 'https://automatisch.io',
|
||||
additionalDrawerLinkText: 'Automatisch',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@@ -6,6 +6,31 @@ import { createRole } from '../../../test/factories/role';
|
||||
import { createUser } from '../../../test/factories/user';
|
||||
|
||||
describe('graphQL getCurrentUser query', () => {
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const invalidUserToken = 'invalid-token';
|
||||
|
||||
const query = `
|
||||
query {
|
||||
getCurrentUser {
|
||||
id
|
||||
email
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidUserToken)
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
let role, currentUser, token, requestObject;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -77,3 +102,4 @@ describe('graphQL getCurrentUser query', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -40,7 +40,23 @@ describe('graphQL getExecutions query', () => {
|
||||
}
|
||||
`;
|
||||
|
||||
describe('and without correct permissions', () => {
|
||||
const invalidToken = 'invalid-token';
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidToken)
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and without permissions', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const userWithoutPermissions = await createUser();
|
||||
const token = createAuthTokenByUserId(userWithoutPermissions.id);
|
||||
@@ -470,3 +486,4 @@ describe('graphQL getExecutions query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -40,6 +40,23 @@ describe('graphQL getFlow query', () => {
|
||||
`;
|
||||
};
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const invalidToken = 'invalid-token';
|
||||
const flow = await createFlow();
|
||||
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidToken)
|
||||
.send({ query: query(flow.id) })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and without permissions', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const userWithoutPermissions = await createUser();
|
||||
@@ -128,7 +145,9 @@ describe('graphQL getFlow query', () => {
|
||||
{
|
||||
appKey: actionStep.appKey,
|
||||
connection: {
|
||||
createdAt: actionConnection.createdAt.getTime().toString(),
|
||||
createdAt: actionConnection.createdAt
|
||||
.getTime()
|
||||
.toString(),
|
||||
id: actionConnection.id,
|
||||
verified: actionConnection.verified,
|
||||
},
|
||||
@@ -215,7 +234,9 @@ describe('graphQL getFlow query', () => {
|
||||
{
|
||||
appKey: actionStep.appKey,
|
||||
connection: {
|
||||
createdAt: actionConnection.createdAt.getTime().toString(),
|
||||
createdAt: actionConnection.createdAt
|
||||
.getTime()
|
||||
.toString(),
|
||||
id: actionConnection.id,
|
||||
verified: actionConnection.verified,
|
||||
},
|
||||
@@ -238,3 +259,4 @@ describe('graphQL getFlow query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -17,6 +17,7 @@ describe('graphQL getRole query', () => {
|
||||
userWithoutPermissions,
|
||||
tokenWithPermissions,
|
||||
tokenWithoutPermissions,
|
||||
invalidToken,
|
||||
permissionOne,
|
||||
permissionTwo;
|
||||
|
||||
@@ -73,8 +74,24 @@ describe('graphQL getRole query', () => {
|
||||
tokenWithoutPermissions = createAuthTokenByUserId(
|
||||
userWithoutPermissions.id
|
||||
);
|
||||
|
||||
invalidToken = 'invalid-token';
|
||||
});
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidToken)
|
||||
.send({ query: queryWithValidRole })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and with valid license', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
@@ -162,3 +179,4 @@ describe('graphQL getRole query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -15,7 +15,8 @@ describe('graphQL getRoles query', () => {
|
||||
userWithPermissions,
|
||||
userWithoutPermissions,
|
||||
tokenWithPermissions,
|
||||
tokenWithoutPermissions;
|
||||
tokenWithoutPermissions,
|
||||
invalidToken;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ name: 'Current user role' });
|
||||
@@ -52,8 +53,24 @@ describe('graphQL getRoles query', () => {
|
||||
tokenWithoutPermissions = createAuthTokenByUserId(
|
||||
userWithoutPermissions.id
|
||||
);
|
||||
|
||||
invalidToken = 'invalid-token';
|
||||
});
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidToken)
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and with valid license', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
@@ -132,3 +149,4 @@ describe('graphQL getRoles query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -16,6 +16,22 @@ describe('graphQL getTrialStatus query', () => {
|
||||
}
|
||||
`;
|
||||
|
||||
const invalidToken = 'invalid-token';
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', invalidToken)
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
let user, userToken;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -98,3 +114,4 @@ describe('graphQL getTrialStatus query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -8,6 +8,31 @@ import { createPermission } from '../../../test/factories/permission';
|
||||
import { createUser } from '../../../test/factories/user';
|
||||
|
||||
describe('graphQL getUser query', () => {
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const invalidUserId = '123123123';
|
||||
|
||||
const query = `
|
||||
query {
|
||||
getUser(id: "${invalidUserId}") {
|
||||
id
|
||||
email
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', 'invalid-token')
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and without permissions', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const userWithoutPermissions = await createUser();
|
||||
@@ -59,7 +84,9 @@ describe('graphQL getUser query', () => {
|
||||
});
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
requestObject = request(app).post('/graphql').set('Authorization', token);
|
||||
requestObject = request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', token);
|
||||
});
|
||||
|
||||
it('should return user data for a valid user id', async () => {
|
||||
@@ -144,3 +171,4 @@ describe('graphQL getUser query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -30,6 +30,20 @@ describe('graphQL getUsers query', () => {
|
||||
}
|
||||
`;
|
||||
|
||||
describe('with unauthenticated user', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const response = await request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', 'invalid-token')
|
||||
.send({ query })
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toEqual('Not Authorised!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with authenticated user', () => {
|
||||
describe('and without permissions', () => {
|
||||
it('should throw not authorized error', async () => {
|
||||
const userWithoutPermissions = await createUser();
|
||||
@@ -72,7 +86,9 @@ describe('graphQL getUsers query', () => {
|
||||
});
|
||||
|
||||
token = createAuthTokenByUserId(currentUser.id);
|
||||
requestObject = request(app).post('/graphql').set('Authorization', token);
|
||||
requestObject = request(app)
|
||||
.post('/graphql')
|
||||
.set('Authorization', token);
|
||||
});
|
||||
|
||||
it('should return users data', async () => {
|
||||
@@ -146,3 +162,4 @@ describe('graphQL getUsers query', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -3,7 +3,7 @@ import jwt from 'jsonwebtoken';
|
||||
import appConfig from '../config/app.js';
|
||||
import User from '../models/user.js';
|
||||
|
||||
export const isAuthenticated = async (_parent, _args, req) => {
|
||||
const isAuthenticated = rule()(async (_parent, _args, req) => {
|
||||
const token = req.headers['authorization'];
|
||||
|
||||
if (token == null) return false;
|
||||
@@ -20,28 +20,18 @@ export const isAuthenticated = async (_parent, _args, req) => {
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
permissions: true,
|
||||
})
|
||||
.throwIfNotFound();
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
export const authenticateUser = async (request, response, next) => {
|
||||
if (await isAuthenticated(null, null, request)) {
|
||||
next();
|
||||
} else {
|
||||
return response.status(401).end();
|
||||
}
|
||||
};
|
||||
|
||||
const isAuthenticatedRule = rule()(isAuthenticated);
|
||||
|
||||
export const authenticationRules = {
|
||||
const authentication = shield(
|
||||
{
|
||||
Query: {
|
||||
'*': isAuthenticatedRule,
|
||||
'*': isAuthenticated,
|
||||
getAutomatischInfo: allow,
|
||||
getConfig: allow,
|
||||
getNotifications: allow,
|
||||
@@ -49,18 +39,16 @@ export const authenticationRules = {
|
||||
listSamlAuthProviders: allow,
|
||||
},
|
||||
Mutation: {
|
||||
'*': isAuthenticatedRule,
|
||||
'*': isAuthenticated,
|
||||
forgotPassword: allow,
|
||||
login: allow,
|
||||
registerUser: allow,
|
||||
resetPassword: allow,
|
||||
},
|
||||
};
|
||||
|
||||
const authenticationOptions = {
|
||||
},
|
||||
{
|
||||
allowExternalErrors: true,
|
||||
};
|
||||
|
||||
const authentication = shield(authenticationRules, authenticationOptions);
|
||||
}
|
||||
);
|
||||
|
||||
export default authentication;
|
||||
|
@@ -1,72 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { allow } from 'graphql-shield';
|
||||
import { isAuthenticated, authenticationRules } from './authentication.js';
|
||||
import { createUser } from '../../test/factories/user.js';
|
||||
import createAuthTokenByUserId from '../helpers/create-auth-token-by-user-id.js';
|
||||
|
||||
describe('isAuthenticated', () => {
|
||||
it('should return false if no token is provided', async () => {
|
||||
const req = { headers: {} };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if token is invalid', async () => {
|
||||
const req = { headers: { authorization: 'invalidToken' } };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true if token is valid and there is a user', async () => {
|
||||
const user = await createUser();
|
||||
const token = createAuthTokenByUserId(user.id);
|
||||
|
||||
const req = { headers: { authorization: token } };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if token is valid and but there is no user', async () => {
|
||||
const user = await createUser();
|
||||
const token = createAuthTokenByUserId(user.id);
|
||||
await user.$query().delete();
|
||||
|
||||
const req = { headers: { authorization: token } };
|
||||
expect(await isAuthenticated(null, null, req)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('authentication rules', () => {
|
||||
const getQueryAndMutationNames = (rules) => {
|
||||
const queries = Object.keys(rules.Query || {});
|
||||
const mutations = Object.keys(rules.Mutation || {});
|
||||
return { queries, mutations };
|
||||
};
|
||||
|
||||
const { queries, mutations } = getQueryAndMutationNames(authenticationRules);
|
||||
|
||||
describe('for queries', () => {
|
||||
queries.forEach((query) => {
|
||||
it(`should apply correct rule for query: ${query}`, () => {
|
||||
const ruleApplied = authenticationRules.Query[query];
|
||||
|
||||
if (query === '*') {
|
||||
expect(ruleApplied.func).toBe(isAuthenticated);
|
||||
} else {
|
||||
expect(ruleApplied).toEqual(allow);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('for mutations', () => {
|
||||
mutations.forEach((mutation) => {
|
||||
it(`should apply correct rule for mutation: ${mutation}`, () => {
|
||||
const ruleApplied = authenticationRules.Mutation[mutation];
|
||||
|
||||
if (mutation === '*') {
|
||||
expect(ruleApplied.func).toBe(isAuthenticated);
|
||||
} else {
|
||||
expect(ruleApplied).toBe(allow);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -1,37 +0,0 @@
|
||||
const authorizationList = {
|
||||
'GET /api/v1/users/:userId': {
|
||||
action: 'read',
|
||||
subject: 'User',
|
||||
},
|
||||
'GET /api/v1/users/': {
|
||||
action: 'read',
|
||||
subject: 'User',
|
||||
},
|
||||
'GET /api/v1/flows/:flowId': {
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
},
|
||||
};
|
||||
|
||||
export const authorizeUser = async (request, response, next) => {
|
||||
const currentRoute =
|
||||
request.method + ' ' + request.baseUrl + request.route.path;
|
||||
const currentRouteRule = authorizationList[currentRoute];
|
||||
|
||||
try {
|
||||
request.currentUser.can(currentRouteRule.action, currentRouteRule.subject);
|
||||
next();
|
||||
} catch (error) {
|
||||
return response.status(403).end();
|
||||
}
|
||||
};
|
||||
|
||||
export const authorizeAdmin = async (request, response, next) => {
|
||||
const role = await request.currentUser.$relatedQuery('role');
|
||||
|
||||
if (role?.isAdmin) {
|
||||
next();
|
||||
} else {
|
||||
return response.status(403).end();
|
||||
}
|
||||
};
|
@@ -1,11 +0,0 @@
|
||||
import appConfig from '../config/app.js';
|
||||
|
||||
export const checkIsCloud = async (request, response, next) => {
|
||||
if (appConfig.isCloud) {
|
||||
next();
|
||||
} else {
|
||||
return response.status(404).end();
|
||||
}
|
||||
};
|
||||
|
||||
export default checkIsCloud;
|
@@ -1,9 +0,0 @@
|
||||
import { hasValidLicense } from './license.ee.js';
|
||||
|
||||
export const checkIsEnterprise = async (request, response, next) => {
|
||||
if (await hasValidLicense()) {
|
||||
next();
|
||||
} else {
|
||||
return response.status(404).end();
|
||||
}
|
||||
};
|
@@ -1,9 +1,6 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import handlebars from 'handlebars';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as handlebars from 'handlebars';
|
||||
|
||||
const compileEmail = (emailPath, replacements = {}) => {
|
||||
const filePath = path.join(__dirname, `../views/emails/${emailPath}.ee.hbs`);
|
||||
|
@@ -1,31 +1,14 @@
|
||||
import logger from './logger.js';
|
||||
import objection from 'objection';
|
||||
const { NotFoundError, DataError } = objection;
|
||||
|
||||
// Do not remove `next` argument as the function signature will not fit for an error handler middleware
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const errorHandler = (error, request, response, next) => {
|
||||
if (error.message === 'Not Found' || error instanceof NotFoundError) {
|
||||
response.status(404).end();
|
||||
const errorHandler = (err, req, res, next) => {
|
||||
if (err.message === 'Not Found') {
|
||||
res.status(404).end();
|
||||
} else {
|
||||
logger.error(err.message + '\n' + err.stack);
|
||||
res.status(err.statusCode || 500).send(err.message);
|
||||
}
|
||||
|
||||
if (notFoundAppError(error)) {
|
||||
response.status(404).end();
|
||||
}
|
||||
|
||||
if (error instanceof DataError) {
|
||||
response.status(400).end();
|
||||
}
|
||||
|
||||
logger.error(error.message + '\n' + error.stack);
|
||||
response.status(error.statusCode || 500).end();
|
||||
};
|
||||
|
||||
const notFoundAppError = (error) => {
|
||||
return (
|
||||
error.message.includes('An application with the') ||
|
||||
error.message.includes("key couldn't be found.")
|
||||
);
|
||||
};
|
||||
|
||||
export default errorHandler;
|
||||
|
@@ -4,8 +4,8 @@ import appConfig from '../config/app.js';
|
||||
const levels = {
|
||||
error: 0,
|
||||
warn: 1,
|
||||
http: 2,
|
||||
info: 3,
|
||||
info: 2,
|
||||
http: 3,
|
||||
debug: 4,
|
||||
};
|
||||
|
||||
|
@@ -1,25 +0,0 @@
|
||||
const paginateRest = async (query, page) => {
|
||||
const pageSize = 10;
|
||||
|
||||
page = parseInt(page, 10);
|
||||
|
||||
if (isNaN(page) || page < 1) {
|
||||
page = 1;
|
||||
}
|
||||
|
||||
const [records, count] = await Promise.all([
|
||||
query.limit(pageSize).offset((page - 1) * pageSize),
|
||||
query.resultSize(),
|
||||
]);
|
||||
|
||||
return {
|
||||
pageInfo: {
|
||||
currentPage: page,
|
||||
totalPages: Math.ceil(count / pageSize),
|
||||
},
|
||||
totalCount: count,
|
||||
records,
|
||||
};
|
||||
};
|
||||
|
||||
export default paginateRest;
|
@@ -1,47 +0,0 @@
|
||||
import serializers from '../serializers/index.js';
|
||||
|
||||
const isPaginated = (object) =>
|
||||
object?.pageInfo &&
|
||||
object?.totalCount !== undefined &&
|
||||
Array.isArray(object?.records);
|
||||
|
||||
const isArray = (object) =>
|
||||
Array.isArray(object) || Array.isArray(object?.records);
|
||||
|
||||
const totalCount = (object) =>
|
||||
isPaginated(object) ? object.totalCount : isArray(object) ? object.length : 1;
|
||||
|
||||
const renderObject = (response, object, options) => {
|
||||
let data = isPaginated(object) ? object.records : object;
|
||||
|
||||
const type = isPaginated(object)
|
||||
? object.records[0].constructor.name
|
||||
: Array.isArray(object)
|
||||
? object?.[0]?.constructor?.name || 'Object'
|
||||
: object.constructor.name;
|
||||
|
||||
const serializer = options?.serializer
|
||||
? serializers[options.serializer]
|
||||
: serializers[type];
|
||||
|
||||
if (serializer) {
|
||||
data = Array.isArray(data)
|
||||
? data.map((item) => serializer(item))
|
||||
: serializer(data);
|
||||
}
|
||||
|
||||
const computedPayload = {
|
||||
data,
|
||||
meta: {
|
||||
type,
|
||||
count: totalCount(object),
|
||||
isArray: isArray(object),
|
||||
currentPage: isPaginated(object) ? object.pageInfo.currentPage : null,
|
||||
totalPages: isPaginated(object) ? object.pageInfo.totalPages : null,
|
||||
},
|
||||
};
|
||||
|
||||
return response.json(computedPayload);
|
||||
};
|
||||
|
||||
export { renderObject };
|
@@ -15,7 +15,7 @@ const webUIHandler = async (app) => {
|
||||
app.use(express.static(webBuildPath));
|
||||
|
||||
app.get('*', (_req, res) => {
|
||||
res.set('Content-Security-Policy', 'frame-ancestors \'none\';');
|
||||
res.set('Content-Security-Policy', 'frame-ancestors: none;');
|
||||
res.set('X-Frame-Options', 'DENY');
|
||||
|
||||
res.sendFile(indexHtml);
|
||||
|
@@ -15,7 +15,6 @@ import Role from './role.js';
|
||||
import Step from './step.js';
|
||||
import Subscription from './subscription.ee.js';
|
||||
import UsageData from './usage-data.ee.js';
|
||||
import Billing from '../helpers/billing/index.ee.js';
|
||||
|
||||
class User extends Base {
|
||||
static tableName = 'users';
|
||||
@@ -144,11 +143,6 @@ class User extends Base {
|
||||
},
|
||||
});
|
||||
|
||||
get authorizedFlows() {
|
||||
const conditions = this.can('read', 'Flow');
|
||||
return conditions.isCreator ? this.$relatedQuery('flows') : Flow.query();
|
||||
}
|
||||
|
||||
login(password) {
|
||||
return bcrypt.compare(password, this.password);
|
||||
}
|
||||
@@ -243,20 +237,6 @@ class User extends Base {
|
||||
return currentUsageData.consumedTaskCount < plan.quota;
|
||||
}
|
||||
|
||||
async getInvoices() {
|
||||
const subscription = await this.$relatedQuery('currentSubscription');
|
||||
|
||||
if (!subscription) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const invoices = await Billing.paddleClient.getInvoices(
|
||||
Number(subscription.paddleSubscriptionId)
|
||||
);
|
||||
|
||||
return invoices;
|
||||
}
|
||||
|
||||
async $beforeInsert(queryContext) {
|
||||
await super.$beforeInsert(queryContext);
|
||||
|
||||
|
@@ -15,17 +15,11 @@ process.on('SIGTERM', async () => {
|
||||
await actionQueue.close();
|
||||
});
|
||||
|
||||
actionQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
actionQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error('Error happened in action queue!', error);
|
||||
});
|
||||
|
||||
export default actionQueue;
|
||||
|
@@ -15,17 +15,11 @@ process.on('SIGTERM', async () => {
|
||||
await deleteUserQueue.close();
|
||||
});
|
||||
|
||||
deleteUserQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
deleteUserQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error('Error happened in delete user queue!', error);
|
||||
});
|
||||
|
||||
export default deleteUserQueue;
|
||||
|
@@ -15,17 +15,11 @@ process.on('SIGTERM', async () => {
|
||||
await emailQueue.close();
|
||||
});
|
||||
|
||||
emailQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
emailQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error('Error happened in email queue!', error);
|
||||
});
|
||||
|
||||
export default emailQueue;
|
||||
|
@@ -15,17 +15,11 @@ process.on('SIGTERM', async () => {
|
||||
await flowQueue.close();
|
||||
});
|
||||
|
||||
flowQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
flowQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error('Error happened in flow queue!', error);
|
||||
});
|
||||
|
||||
export default flowQueue;
|
||||
|
@@ -18,20 +18,11 @@ process.on('SIGTERM', async () => {
|
||||
await removeCancelledSubscriptionsQueue.close();
|
||||
});
|
||||
|
||||
removeCancelledSubscriptionsQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
removeCancelledSubscriptionsQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error(
|
||||
'Error happened in remove cancelled subscriptions queue!',
|
||||
error
|
||||
);
|
||||
});
|
||||
|
||||
removeCancelledSubscriptionsQueue.add('remove-cancelled-subscriptions', null, {
|
||||
|
@@ -15,17 +15,11 @@ process.on('SIGTERM', async () => {
|
||||
await triggerQueue.close();
|
||||
});
|
||||
|
||||
triggerQueue.on('error', (error) => {
|
||||
if (error.code === CONNECTION_REFUSED) {
|
||||
logger.error(
|
||||
'Make sure you have installed Redis and it is running.',
|
||||
error
|
||||
);
|
||||
|
||||
triggerQueue.on('error', (err) => {
|
||||
if (err.code === CONNECTION_REFUSED) {
|
||||
logger.error('Make sure you have installed Redis and it is running.', err);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
logger.error('Error happened in trigger queue!', error);
|
||||
});
|
||||
|
||||
export default triggerQueue;
|
||||
|
@@ -1,18 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../../helpers/authentication.js';
|
||||
import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||
import getAdminAppAuthClientsAction from '../../../../controllers/api/v1/admin/app-auth-clients/get-app-auth-client.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/:appAuthClientId',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getAdminAppAuthClientsAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,18 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../../helpers/authentication.js';
|
||||
import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||
import getPermissionsCatalogAction from '../../../../controllers/api/v1/admin/permissions/get-permissions-catalog.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/catalog',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getPermissionsCatalogAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,27 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../../helpers/authentication.js';
|
||||
import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||
import getRolesAction from '../../../../controllers/api/v1/admin/roles/get-roles.ee.js';
|
||||
import getRoleAction from '../../../../controllers/api/v1/admin/roles/get-role.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getRolesAction)
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:roleId',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getRoleAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,27 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../../helpers/authentication.js';
|
||||
import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||
import getSamlAuthProvidersAction from '../../../../controllers/api/v1/admin/saml-auth-providers/get-saml-auth-providers.ee.js';
|
||||
import getSamlAuthProviderAction from '../../../../controllers/api/v1/admin/saml-auth-providers/get-saml-auth-provider.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getSamlAuthProvidersAction)
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:samlAuthProviderId',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getSamlAuthProviderAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,27 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../../helpers/authentication.js';
|
||||
import { authorizeAdmin } from '../../../../helpers/authorization.js';
|
||||
import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js';
|
||||
import getUsersAction from '../../../../controllers/api/v1/admin/users/get-users.ee.js';
|
||||
import getUserAction from '../../../../controllers/api/v1/admin/users/get-user.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getUsersAction)
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:userId',
|
||||
authenticateUser,
|
||||
authorizeAdmin,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getUserAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,16 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../helpers/authentication.js';
|
||||
import { checkIsEnterprise } from '../../../helpers/check-is-enterprise.js';
|
||||
import getAppAuthClientAction from '../../../controllers/api/v1/app-auth-clients/get-app-auth-client.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/:appAuthClientId',
|
||||
authenticateUser,
|
||||
checkIsEnterprise,
|
||||
asyncHandler(getAppAuthClientAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,10 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../helpers/authentication.js';
|
||||
import getAppAction from '../../../controllers/api/v1/apps/get-app.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/:appKey', authenticateUser, asyncHandler(getAppAction));
|
||||
|
||||
export default router;
|
@@ -1,15 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import versionAction from '../../../controllers/api/v1/automatisch/version.js';
|
||||
import notificationsAction from '../../../controllers/api/v1/automatisch/notifications.js';
|
||||
import infoAction from '../../../controllers/api/v1/automatisch/info.js';
|
||||
import licenseAction from '../../../controllers/api/v1/automatisch/license.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/version', asyncHandler(versionAction));
|
||||
router.get('/notifications', asyncHandler(notificationsAction));
|
||||
router.get('/info', asyncHandler(infoAction));
|
||||
router.get('/license', asyncHandler(licenseAction));
|
||||
|
||||
export default router;
|
@@ -1,16 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../helpers/authentication.js';
|
||||
import { authorizeUser } from '../../../helpers/authorization.js';
|
||||
import getFlowAction from '../../../controllers/api/v1/flows/get-flow.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/:flowId',
|
||||
authenticateUser,
|
||||
authorizeUser,
|
||||
asyncHandler(getFlowAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,24 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../helpers/authentication.js';
|
||||
import checkIsCloud from '../../../helpers/check-is-cloud.js';
|
||||
import getPlansAction from '../../../controllers/api/v1/payment/get-plans.ee.js';
|
||||
import getPaddleInfoAction from '../../../controllers/api/v1/payment/get-paddle-info.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get(
|
||||
'/plans',
|
||||
authenticateUser,
|
||||
checkIsCloud,
|
||||
asyncHandler(getPlansAction)
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/paddle-info',
|
||||
authenticateUser,
|
||||
checkIsCloud,
|
||||
asyncHandler(getPaddleInfoAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,26 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { authenticateUser } from '../../../helpers/authentication.js';
|
||||
import checkIsCloud from '../../../helpers/check-is-cloud.js';
|
||||
import getCurrentUserAction from '../../../controllers/api/v1/users/get-current-user.js';
|
||||
import getUserTrialAction from '../../../controllers/api/v1/users/get-user-trial.ee.js';
|
||||
import getInvoicesAction from '../../../controllers/api/v1/users/get-invoices.ee.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/me', authenticateUser, asyncHandler(getCurrentUserAction));
|
||||
router.get(
|
||||
'/invoices',
|
||||
authenticateUser,
|
||||
checkIsCloud,
|
||||
asyncHandler(getInvoicesAction)
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:userId/trial',
|
||||
authenticateUser,
|
||||
checkIsCloud,
|
||||
asyncHandler(getUserTrialAction)
|
||||
);
|
||||
|
||||
export default router;
|
@@ -1,9 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import indexAction from '../controllers/healthcheck/index.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/', asyncHandler(indexAction));
|
||||
|
||||
export default router;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user