mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 08:58:26 +00:00
Merge branch 'main' into feat/steps-v2-alignment-style-improvement
This commit is contained in:
commit
6e0d9b8073
16 changed files with 3110 additions and 155 deletions
94
.github/workflows/cypress-appbuilder.yml
vendored
94
.github/workflows/cypress-appbuilder.yml
vendored
|
|
@ -2,7 +2,7 @@ name: Cypress App-Builder
|
|||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, unlabeled, closed]
|
||||
types: [labeled]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
|
|
@ -12,22 +12,18 @@ env:
|
|||
jobs:
|
||||
Cypress-App-Builder:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
if: |
|
||||
github.event.action == 'labeled' &&
|
||||
(
|
||||
github.event.label.name == 'run-cypress' ||
|
||||
github.event.label.name == 'run-ce-app-builder' ||
|
||||
github.event.label.name == 'run-ee-app-builder'
|
||||
)
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ce-app-builder') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ee-app-builder') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-cypress')
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
edition: >-
|
||||
${{
|
||||
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ce-app-builder') && fromJson('["ce"]') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ee-app-builder') && fromJson('["ee"]') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-cypress') && fromJson('["ce", "ee"]') ||
|
||||
fromJson('[]')
|
||||
}}
|
||||
|
||||
|
|
@ -164,8 +160,8 @@ jobs:
|
|||
|
||||
Cypress-App-builder-Subpath:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'run-cypress-app-builder-subpath' }}
|
||||
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-cypress-app-builder-subpath')
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -173,82 +169,6 @@ jobs:
|
|||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
|
||||
# Create Docker Buildx builder with platform configuration
|
||||
- name: Set up Docker Buildx
|
||||
run: |
|
||||
mkdir -p ~/.docker/cli-plugins
|
||||
curl -SL https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
|
||||
chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||
docker buildx use mybuilder
|
||||
|
||||
- name: Set DOCKER_CLI_EXPERIMENTAL
|
||||
run: echo "DOCKER_CLI_EXPERIMENTAL=enabled" >> $GITHUB_ENV
|
||||
|
||||
- name: use mybuilder buildx
|
||||
run: docker buildx use mybuilder
|
||||
|
||||
- name: Build docker image
|
||||
run: docker buildx build --platform=linux/amd64 -f docker/production.Dockerfile . -t tooljet/tj-osv:cypressplaform
|
||||
|
||||
- name: Set up environment variables
|
||||
run: |
|
||||
echo "TOOLJET_HOST=http://localhost:3000" >> .env
|
||||
echo "LOCKBOX_MASTER_KEY=cd97331a419c09387bef49787f7da8d2a81d30733f0de6bed23ad8356d2068b2" >> .env
|
||||
echo "SECRET_KEY_BASE=7073b9a35a15dd20914ae17e36a693093f25b74b96517a5fec461fc901c51e011cd142c731bee48c5081ec8bac321c1f259ef097ef2a16f25df17a3798c03426" >> .env
|
||||
echo "PG_DB=tooljet_development" >> .env
|
||||
echo "PG_USER=postgres" >> .env
|
||||
echo "PG_HOST=postgres" >> .env
|
||||
echo "PG_PASS=postgres" >> .env
|
||||
echo "PG_PORT=5432" >> .env
|
||||
echo "ENABLE_TOOLJET_DB=true" >> .env
|
||||
echo "TOOLJET_DB=tooljet_db" >> .env
|
||||
echo "TOOLJET_DB_USER=postgres" >> .env
|
||||
echo "TOOLJET_DB_HOST=postgres" >> .env
|
||||
echo "TOOLJET_DB_PASS=postgres" >> .env
|
||||
echo "PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj" >> .env
|
||||
echo "PGRST_HOST=postgrest" >> .env
|
||||
echo "PGRST_DB_URI=postgres://postgres:postgres@postgres/tooljet_db" >> .env
|
||||
echo "SSO_GIT_OAUTH2_CLIENT_ID=dummy" >> .env
|
||||
echo "SSO_GIT_OAUTH2_CLIENT_SECRET=dummy" >> .env
|
||||
echo "SSO_GIT_OAUTH2_HOST=dummy" >> .env
|
||||
echo "SSO_GOOGLE_OAUTH2_CLIENT_ID=dummy" >> .env
|
||||
echo "SUB_PATH=/apps/tooljet/" >> .env
|
||||
echo "NODE_ENV=production" >> .env
|
||||
echo "SERVE_CLIENT=true" >> .env
|
||||
echo "ENABLE_PRIVATE_APP_EMBED=true" >> .env
|
||||
|
||||
- name: Pulling the docker-compose file
|
||||
run: curl -LO https://tooljet-test.s3.us-west-1.amazonaws.com/docker-compose.yaml && mkdir postgres_data
|
||||
|
||||
- name: Run docker-compose file
|
||||
run: docker-compose up -d
|
||||
|
||||
- name: Checking containers
|
||||
run: docker ps -a
|
||||
|
||||
- name: docker logs
|
||||
run: sudo docker logs Tooljet-app
|
||||
|
||||
- name: Wait for the server to be ready
|
||||
run: |
|
||||
timeout 1500 bash -c '
|
||||
until curl --silent --fail http://localhost:80/apps/tooljet/; do
|
||||
sleep 5
|
||||
done'
|
||||
|
||||
- name: Seeding (Setup Super Admin)
|
||||
run: |
|
||||
curl 'http://localhost:3000/api/onboarding/setup-super-admin' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"companyName": "ToolJet",,
|
||||
"name": "The Developer",
|
||||
"workspaceName": "Tooljet'\''s workspace",
|
||||
"email": "dev@tooljet.io",
|
||||
"password": "password"
|
||||
}'
|
||||
|
||||
- name: Create Cypress environment file
|
||||
id: create-json
|
||||
uses: jsdaniell/create-json@1.1.2
|
||||
|
|
|
|||
17
.github/workflows/cypress-marketplace.yml
vendored
17
.github/workflows/cypress-marketplace.yml
vendored
|
|
@ -2,7 +2,7 @@ name: Cypress Marketplace
|
|||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, unlabeled, closed]
|
||||
types: [labeled]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
@ -14,13 +14,9 @@ jobs:
|
|||
Cypress-Marketplace:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
if: |
|
||||
github.event.action == 'labeled' &&
|
||||
(
|
||||
github.event.label.name == 'run-cypress' ||
|
||||
github.event.label.name == 'run-ce-cypress-marketplace' ||
|
||||
github.event.label.name == 'run-ee-cypress-marketplace'
|
||||
)
|
||||
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-marketplace') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-marketplace')
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
@ -44,7 +40,7 @@ jobs:
|
|||
mkdir -p ~/.docker/cli-plugins
|
||||
curl -SL https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
|
||||
chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64,linux/amd64/v2,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||
docker buildx create --name mybuilder --platform linux/arm64,linux/amd64
|
||||
docker buildx use mybuilder
|
||||
|
||||
- name: Set DOCKER_CLI_EXPERIMENTAL
|
||||
|
|
@ -189,7 +185,8 @@ jobs:
|
|||
Cypress-Marketplace-Subpath:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
if: ${{ github.event.action == 'labeled' && github.event.label.name == 'run-cypress-marketplace-subpath' }}
|
||||
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-cypress-marketplace-subpath')
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
|
|||
13
.github/workflows/cypress-platform.yml
vendored
13
.github/workflows/cypress-platform.yml
vendored
|
|
@ -2,7 +2,7 @@ name: Cypress Platform
|
|||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, unlabeled, closed]
|
||||
types: [labeled]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
|
|
@ -12,14 +12,9 @@ env:
|
|||
jobs:
|
||||
Cypress-Platform:
|
||||
runs-on: ubuntu-22.04
|
||||
if: |
|
||||
github.event.action == 'labeled' &&
|
||||
(
|
||||
github.event.label.name == 'run-cypress' ||
|
||||
github.event.label.name == 'run-ce-cypress-platform' ||
|
||||
github.event.label.name == 'run-ee-cypress-platform'
|
||||
)
|
||||
|
||||
if: contains(github.event.pull_request.labels.*.name, 'run-cypress') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ce-cypress-platform') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'run-ee-cypress-platform')
|
||||
strategy:
|
||||
matrix:
|
||||
edition: >-
|
||||
|
|
|
|||
43
.github/workflows/render-preview-deploy.yml
vendored
43
.github/workflows/render-preview-deploy.yml
vendored
|
|
@ -12,7 +12,7 @@ permissions:
|
|||
|
||||
jobs:
|
||||
|
||||
# Community Edition
|
||||
# Community Edition CE
|
||||
create-ce-review-app:
|
||||
if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'create-ce-review-app' || github.event.label.name == 'review-app') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -72,7 +72,7 @@ jobs:
|
|||
"envVars": [
|
||||
{
|
||||
"key": "PG_HOST",
|
||||
"value": "${{ secrets.RENDER_PG_HOST }}"
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"key": "PG_PORT",
|
||||
|
|
@ -80,11 +80,11 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "PG_USER",
|
||||
"value": "${{ secrets.RENDER_PG_USER }}"
|
||||
"value": "tooljet"
|
||||
},
|
||||
{
|
||||
"key": "PG_PASS",
|
||||
"value": "${{ secrets.RENDER_PG_PASS }}"
|
||||
"value": "postgres"
|
||||
},
|
||||
{
|
||||
"key": "PG_DB",
|
||||
|
|
@ -96,15 +96,15 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_HOST",
|
||||
"value": "${{ secrets.RENDER_PG_HOST }}"
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_USER",
|
||||
"value": "${{ secrets.RENDER_PG_USER }}"
|
||||
"value": "tooljet"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_PASS",
|
||||
"value": "${{ secrets.RENDER_PG_PASS }}"
|
||||
"value": "postgres"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_PORT",
|
||||
|
|
@ -116,7 +116,7 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "PGRST_DB_URI",
|
||||
"value": "postgres://${{ secrets.RENDER_PG_USER }}:${{ secrets.RENDER_PG_PASS }}@${{ secrets.RENDER_PG_HOST }}/${{ env.PR_NUMBER }}-ce-tjdb"
|
||||
"value": "postgres://tooljet:postgres@localhost/${{ env.PR_NUMBER }}-ce-tjdb"
|
||||
},
|
||||
{
|
||||
"key": "PGRST_HOST",
|
||||
|
|
@ -162,18 +162,6 @@ jobs:
|
|||
"key": "SMTP_PASSWORD",
|
||||
"value": "${{ secrets.RENDER_SMTP_PASSWORD }}"
|
||||
},
|
||||
{
|
||||
"key": "TEMPORAL_SERVER_ADDRESS",
|
||||
"value": "https://auto-setup-1-25-1.onrender.com"
|
||||
},
|
||||
{
|
||||
"key": "TEMPORAL_TASK_QUEUE_NAME_FOR_WORKFLOWS",
|
||||
"value": "tooljet-ce-pr-${{ env.PR_NUMBER }}"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_WORKFLOWS_TEMPORAL_NAMESPACE",
|
||||
"value": "default"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_MARKETPLACE_URL",
|
||||
"value": "${{ secrets.MARKETPLACE_BUCKET }}"
|
||||
|
|
@ -424,7 +412,7 @@ jobs:
|
|||
"envVars": [
|
||||
{
|
||||
"key": "PG_HOST",
|
||||
"value": "${{ secrets.RENDER_PG_HOST }}"
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"key": "PG_PORT",
|
||||
|
|
@ -432,11 +420,11 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "PG_USER",
|
||||
"value": "${{ secrets.RENDER_PG_USER }}"
|
||||
"value": "tooljet"
|
||||
},
|
||||
{
|
||||
"key": "PG_PASS",
|
||||
"value": "${{ secrets.RENDER_PG_PASS }}"
|
||||
"value": "postgres"
|
||||
},
|
||||
{
|
||||
"key": "PG_DB",
|
||||
|
|
@ -448,15 +436,15 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_HOST",
|
||||
"value": "${{ secrets.RENDER_PG_HOST }}"
|
||||
"value": "localhost"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_USER",
|
||||
"value": "${{ secrets.RENDER_PG_USER }}"
|
||||
"value": "tooljet"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_PASS",
|
||||
"value": "${{ secrets.RENDER_PG_PASS }}"
|
||||
"value": "postgres"
|
||||
},
|
||||
{
|
||||
"key": "TOOLJET_DB_PORT",
|
||||
|
|
@ -468,7 +456,7 @@ jobs:
|
|||
},
|
||||
{
|
||||
"key": "PGRST_DB_URI",
|
||||
"value": "postgres://${{ secrets.RENDER_PG_USER }}:${{ secrets.RENDER_PG_PASS }}@${{ secrets.RENDER_PG_HOST }}/${{ env.PR_NUMBER }}-ee-tjdb"
|
||||
"value": "postgres://tooljet:postgres@localhost/${{ env.PR_NUMBER }}-ee-tjdb"
|
||||
},
|
||||
{
|
||||
"key": "PGRST_HOST",
|
||||
|
|
@ -1124,4 +1112,3 @@ jobs:
|
|||
# } catch (e) {
|
||||
# console.log(e)
|
||||
# }
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ Cypress.Commands.add("apiCreateWorkspace", (workspaceName, workspaceSlug) => {
|
|||
{ log: false }
|
||||
).then((response) => {
|
||||
expect(response.status).to.equal(201);
|
||||
return response;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -522,10 +522,8 @@ describe("Manage Groups", () => {
|
|||
commonSelectors.buttonSelector(exportAppModalText.exportSelectedVersion)
|
||||
).click();
|
||||
cy.exec("ls ./cypress/downloads/").then((result) => {
|
||||
cy.log(result);
|
||||
const downloadedAppExportFileName = result.stdout.split("\n")[0];
|
||||
exportedFilePath = `cypress/downloads/${downloadedAppExportFileName}`;
|
||||
cy.log(exportedFilePath);
|
||||
cy.get(importSelectors.dropDownMenu).should("be.visible").click();
|
||||
cy.get(importSelectors.importOptionInput).selectFile(exportedFilePath, {
|
||||
force: true,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,382 @@
|
|||
import { fake } from "Fixtures/fake";
|
||||
import {
|
||||
createUser, getAllUsers, getUser, updateUser, createGroup, validateUserInGroup, updateUserRole,
|
||||
getAllWorkspaces, replaceUserWorkspace, replaceUserWorkspacesRelations
|
||||
} from 'Support/utils/api';
|
||||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { commonSelectors } from 'Selectors/common';
|
||||
import { searchUser, navigateToManageUsers, logout, navigateToManageGroups } from 'Support/utils/common';
|
||||
describe("API Test", () => {
|
||||
|
||||
const sanitize = (str) => str.toLowerCase().replace(/[^A-Za-z]/g, "");
|
||||
let userId;
|
||||
let workspaceId;
|
||||
const data = {
|
||||
firstName: fake.firstName,
|
||||
lastName: fake.lastName,
|
||||
firstName1: fake.firstName,
|
||||
lastName1: fake.lastName,
|
||||
firstName2: fake.firstName,
|
||||
lastName2: fake.lastName,
|
||||
email: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
email1: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
email2: fake.email.toLowerCase().replaceAll("[^A-Za-z]", ""),
|
||||
workspaceName: sanitize(fake.lastName),
|
||||
workspaceSlug: sanitize(fake.lastName),
|
||||
workspaceName1: sanitize(fake.firstName),
|
||||
workspaceSlug1: sanitize(fake.firstName),
|
||||
group1: sanitize(fake.firstName),
|
||||
group2: sanitize(fake.firstName),
|
||||
group3: sanitize(fake.firstName),
|
||||
group4: sanitize(fake.firstName),
|
||||
group5: sanitize(fake.firstName),
|
||||
appName: fake.companyName
|
||||
};
|
||||
|
||||
//user with all valid details
|
||||
const userData = {
|
||||
name: `${data.firstName} ${data.lastName}`,
|
||||
email: data.email,
|
||||
password: "password",
|
||||
status: "active",
|
||||
workspaces: [
|
||||
{
|
||||
name: "My workspace",
|
||||
status: "active",
|
||||
groups: [
|
||||
{ name: data.group1 },
|
||||
{ name: data.group2 }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: data.workspaceName,
|
||||
status: "active",
|
||||
role: "builder",
|
||||
groups: [{ name: data.group3 }]
|
||||
},
|
||||
{
|
||||
name: data.workspaceName1,
|
||||
status: "archived",
|
||||
role: "admin",
|
||||
groups: [{ name: data.group4 }]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
});
|
||||
|
||||
it("Create user with valid details", () => {
|
||||
// create multiple groups in different workspaces
|
||||
navigateToManageGroups();
|
||||
[data.group1, data.group2, data.group5].forEach(createGroup);
|
||||
|
||||
//builder group
|
||||
cy.get(groupsSelector.groupLink(data.group5)).click();
|
||||
cy.get(groupsSelector.permissionsLink).click();
|
||||
cy.get(groupsSelector.appsCreateCheck).check();
|
||||
|
||||
[
|
||||
{ name: data.workspaceName, slug: data.workspaceSlug, group: data.group3 },
|
||||
{ name: data.workspaceName1, slug: data.workspaceSlug1, group: data.group4 }
|
||||
].forEach(({ name, slug, group }) => {
|
||||
cy.apiCreateWorkspace(name, slug);
|
||||
cy.visit(slug);
|
||||
navigateToManageGroups();
|
||||
createGroup(group);
|
||||
});
|
||||
|
||||
// Added valid user and logged-in in the workpsace
|
||||
cy.visit("/my-workspace");
|
||||
cy.wait(500);
|
||||
createUser(userData).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
userId = response.body.id;
|
||||
workspaceId = response.body.workspaces[0].id;
|
||||
navigateToManageUsers();
|
||||
searchUser(data.email);
|
||||
cy.contains("td", data.email)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get("td small").should("have.text", "active");
|
||||
});
|
||||
|
||||
validateUserInGroup(data.email, "my-workspace", "end-user");
|
||||
validateUserInGroup(data.email, data.workspaceSlug, "builder");
|
||||
validateUserInGroup(data.email, data.workspaceSlug1, "admin", false);
|
||||
cy.apiLogout();
|
||||
|
||||
cy.apiLogin(data.email, "password");
|
||||
cy.visit("/my-workspace");
|
||||
cy.get(commonSelectors.workspaceName).should("have.text", "My workspace");
|
||||
logout();
|
||||
|
||||
//Retrieve all users, a specific user by ID, and all workspaces
|
||||
cy.defaultWorkspaceLogin();
|
||||
navigateToManageUsers();
|
||||
let number = 0;
|
||||
cy.get('[data-cy="title-users-page"]').invoke('text').then((text) => {
|
||||
number = parseInt(text.match(/\d+/)[0], 10);
|
||||
});
|
||||
|
||||
getAllUsers().then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
//expect(response.body.length).to.eq(number); //error due to removal of user from instance
|
||||
});
|
||||
|
||||
getUser(userId).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
expect(response.body.name).to.eq(`${data.firstName} ${data.lastName}`);
|
||||
});
|
||||
|
||||
getAllWorkspaces().then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Handles user creation errors', () => {
|
||||
const invalidUserData = [
|
||||
{ // Duplicate user
|
||||
data: { ...userData },
|
||||
expectedStatus: 422,
|
||||
expectedMessage: 'Already exists!'
|
||||
},
|
||||
{ // Invalid email and long password
|
||||
data: {
|
||||
...userData,
|
||||
name: `${data.firstName1} ${data.lastName1}`,
|
||||
email: 'invalid-email',
|
||||
password: 'a'.repeat(101)
|
||||
},
|
||||
expectedStatus: 400,
|
||||
expectedMessages: ['email must be an email', 'password must be shorter than or equal to 100 characters']
|
||||
},
|
||||
{ // Non-existing group
|
||||
data: {
|
||||
...userData,
|
||||
name: `${data.firstName1} ${data.lastName1}`,
|
||||
email: `${data.email1}`,
|
||||
workspaces: [{ name: 'My workspace', status: 'active', groups: [{ name: 'NonExistingGroup' }] }]
|
||||
},
|
||||
expectedStatus: 400,
|
||||
expectedMessage: 'Group permission id or name not found:'
|
||||
},
|
||||
{ // Non-existing workspace
|
||||
data: {
|
||||
...userData,
|
||||
name: `${data.firstName1} ${data.lastName1}`,
|
||||
email: `${data.email1}`,
|
||||
workspaces: [{ name: 'NonExistingWorkspace', status: 'active' }]
|
||||
},
|
||||
expectedStatus: 400,
|
||||
expectedMessage: 'The workspaces id or name do not exist:'
|
||||
}
|
||||
];
|
||||
|
||||
invalidUserData.forEach(({ data, expectedStatus, expectedMessages, expectedMessage }) => {
|
||||
createUser(data).then((response) => {
|
||||
expect(response.status).to.eq(expectedStatus);
|
||||
if (expectedMessages) {
|
||||
expectedMessages.forEach(msg => expect(response.body.message).to.include(msg));
|
||||
} else {
|
||||
expect(response.body.message).to.include(expectedMessage);
|
||||
}
|
||||
});
|
||||
});
|
||||
//Conflict permission
|
||||
const enduserData = {
|
||||
...userData,
|
||||
name: `${data.firstName1} ${data.lastName1}`,
|
||||
email: `${data.email1}`,
|
||||
workspaces: [{ name: 'My workspace', status: 'active', groups: [{ name: data.group5 }] }]
|
||||
}
|
||||
createUser(enduserData).then((response) => {
|
||||
expect(response.status).to.eq(400);
|
||||
expect(response.body.message.title).to.include("Conflicting permissions");
|
||||
})
|
||||
});
|
||||
|
||||
it("Update user details and workspaces relations", () => {
|
||||
const updatedUserData = {
|
||||
name: `${data.firstName1} ${data.lastName1}`,
|
||||
email: data.email1,
|
||||
password: "updatedpassword"
|
||||
}
|
||||
updateUser(userId, updatedUserData).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
})
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(updatedUserData.email, updatedUserData.password);
|
||||
cy.apiLogout();
|
||||
|
||||
// Replace user workspaces relations
|
||||
cy.apiLogin();
|
||||
validateUserInGroup(updatedUserData.email, "my-workspace", data.group2);
|
||||
validateUserInGroup(updatedUserData.email, data.workspaceSlug, data.group3);
|
||||
cy.visit(data.workspaceSlug1);
|
||||
navigateToManageUsers();
|
||||
searchUser(updatedUserData.email);
|
||||
cy.contains("td", updatedUserData.email);
|
||||
|
||||
replaceUserWorkspacesRelations(userId, [
|
||||
{ name: "My workspace", status: "active", role: "end-user", groups: [{ name: data.group1 }] },
|
||||
{ name: data.workspaceName, status: "active", role: "builder", groups: [] }
|
||||
]).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
navigateToManageUsers();
|
||||
validateUserInGroup(updatedUserData.email, "my-workspace", data.group2, false);
|
||||
validateUserInGroup(updatedUserData.email, data.workspaceSlug, data.group3, false);
|
||||
|
||||
cy.visit(data.workspaceSlug1);
|
||||
navigateToManageUsers();
|
||||
searchUser(updatedUserData.email);
|
||||
cy.get('[data-cy="text-no-result-found"]').contains("No result found");
|
||||
replaceUserWorkspacesRelations(userId, []).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
cy.visit("my-workspace");
|
||||
navigateToManageUsers();
|
||||
searchUser(updatedUserData.email);
|
||||
cy.get('[data-cy="text-no-result-found"]').contains("No result found");
|
||||
});
|
||||
|
||||
it("update user role", () => {
|
||||
const userData2 = {
|
||||
name: `${data.firstName} ${data.lastName}`,
|
||||
email: data.email,
|
||||
password: "password",
|
||||
status: "active",
|
||||
workspaces: [
|
||||
{
|
||||
name: "My workspace",
|
||||
status: "active"
|
||||
}
|
||||
]
|
||||
}
|
||||
let userId1;
|
||||
let workspaceId1;
|
||||
createUser(userData2).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
userId1 = response.body.id;
|
||||
workspaceId1 = response.body.workspaces[0].id;
|
||||
//update role to builder and validate user in builder's group
|
||||
updateUserRole(workspaceId1, { newRole: "builder", userId: userId1 })
|
||||
.then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
validateUserInGroup(userData2.email, "my-workspace", "builder");
|
||||
|
||||
//update role to end-user and validate user is removed from builder's group
|
||||
updateUserRole(workspaceId1, { newRole: "end-user", userId: userId1 })
|
||||
.then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
validateUserInGroup(userData2.email, "my-workspace", data.group5, false);
|
||||
|
||||
// update role to builders and validate app's owner role can't be updated
|
||||
updateUserRole(workspaceId1, { newRole: "builder", userId: userId1 })
|
||||
.then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
cy.apiLogout();
|
||||
cy.apiLogin(userData2.email, userData2.password);
|
||||
cy.apiCreateApp(data.appName);
|
||||
cy.apiLogout();
|
||||
cy.defaultWorkspaceLogin();
|
||||
updateUserRole(workspaceId1, { newRole: "end-user", userId: userId1 })
|
||||
.then((response) => {
|
||||
expect(response.status).to.eq(400);
|
||||
expect(response.body.message.title).to.include("Can not change user role");
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
const userData3 = {
|
||||
name: `${data.firstName2} ${data.lastName2}`,
|
||||
email: data.email2,
|
||||
password: "password",
|
||||
status: "active",
|
||||
workspaces: [
|
||||
{
|
||||
name: "My workspace",
|
||||
status: "active",
|
||||
groups: [
|
||||
{ name: data.group1 },
|
||||
{ name: data.group2 }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: data.workspaceName,
|
||||
status: "active",
|
||||
role: "builder",
|
||||
groups: [{ name: data.group3 }]
|
||||
},
|
||||
{
|
||||
name: data.workspaceName1,
|
||||
status: "archived",
|
||||
role: "admin",
|
||||
groups: [{ name: data.group4 }]
|
||||
}
|
||||
]
|
||||
};
|
||||
it("Replace user workspace", () => {
|
||||
let userId1, workspaceId1;
|
||||
createUser(userData3).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
userId1 = response.body.id;
|
||||
workspaceId1 = response.body.workspaces[0].id;
|
||||
|
||||
// Helper function to replace user workspace and validate response
|
||||
const replaceAndValidate = (payload, expectedStatus = 200) => {
|
||||
return replaceUserWorkspace(userId1, workspaceId1, payload).then((response) => {
|
||||
expect(response.status).to.eq(expectedStatus);
|
||||
});
|
||||
};
|
||||
|
||||
// No change if empty request body
|
||||
replaceAndValidate({}).then(() => {
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group1);
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group2);
|
||||
});
|
||||
|
||||
// Archive the user and verify status
|
||||
replaceAndValidate({ status: "archived" }).then(() => {
|
||||
navigateToManageUsers();
|
||||
searchUser(userData3.email);
|
||||
cy.contains("td", userData3.email)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get("td small").should("have.text", "archived");
|
||||
});
|
||||
});
|
||||
|
||||
// Reactivate user and validate groups
|
||||
replaceAndValidate({ status: "active" }).then(() => {
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group1);
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group2);
|
||||
});
|
||||
|
||||
// Update groups and validate removal
|
||||
replaceAndValidate({ groups: [{ name: data.group1 }] }).then(() => {
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group2, false);
|
||||
});
|
||||
|
||||
//Empty group array, user removed from groups
|
||||
replaceAndValidate({ groups: [] }).then(() => {
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group1, false);
|
||||
});
|
||||
|
||||
//Conflict permission
|
||||
replaceAndValidate({ groups: [{ name: data.group5 }] }, 400);
|
||||
|
||||
//Add user in groups and validate
|
||||
replaceAndValidate({ groups: [{ name: data.group1 }, { name: data.group2 }] });
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group1);
|
||||
validateUserInGroup(userData3.email, "my-workspace", data.group2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
import { importApp, exportApp, allAppsDetails } from 'Support/utils/api';
|
||||
import { fake } from "Fixtures/fake";
|
||||
|
||||
describe("Export and Import API ", () => {
|
||||
|
||||
const sanitize = (str) => str.toLowerCase().replace(/[^A-Za-z]/g, "");
|
||||
const data = {
|
||||
workspaceName: sanitize(fake.lastName),
|
||||
workspaceSlug: sanitize(fake.lastName),
|
||||
}
|
||||
|
||||
const fixtureFiles = {
|
||||
requestData: "templates/import_unnamed_file.json",
|
||||
requestData2: "templates/import_named_file.json",
|
||||
requestData3: "templates/three-versions.json",
|
||||
};
|
||||
let requestData, requestData2, requestData3;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.defaultWorkspaceLogin();
|
||||
|
||||
const fixturePromises = Object.entries(fixtureFiles).map(([key, file]) =>
|
||||
cy.fixture(file).then((data) => ({ key, data }))
|
||||
);
|
||||
|
||||
// Assign loaded data to respective variables
|
||||
return Promise.all(fixturePromises).then((results) => {
|
||||
results.forEach(({ key, data }) => {
|
||||
({ requestData, requestData2, requestData3 }[key] = data);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
it("Import App API", () => {
|
||||
const workspaceId = Cypress.env("workspaceId");
|
||||
|
||||
importApp(workspaceId, requestData).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.message).to.include("App imported successfully into workspace");
|
||||
});
|
||||
|
||||
//Invalid access token and workspace
|
||||
importApp(workspaceId, requestData, {
|
||||
Authorization: "Basic xyz",
|
||||
"Content-Type": "application/json"
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eq(403);
|
||||
});
|
||||
|
||||
importApp(workspaceId, requestData, {
|
||||
Authorization: "",
|
||||
"Content-Type": "application/json"
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eq(403);
|
||||
});
|
||||
|
||||
importApp(`${workspaceId}ee`, requestData).then((response) => {
|
||||
expect(response.status).to.eq(400);
|
||||
});
|
||||
|
||||
//Import named file
|
||||
importApp(workspaceId, requestData2).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.message).to.include("App imported successfully into workspace");
|
||||
});
|
||||
cy.reload();
|
||||
cy.get('[data-cy="app_json-title"]').should("exist");
|
||||
|
||||
//duplicate app
|
||||
importApp(workspaceId, requestData2).then((response) => {
|
||||
expect(response.status).to.eq(409);
|
||||
expect(response.body.message).to.include("App with app_json already exists in the workspace");
|
||||
});
|
||||
cy.deleteApp("app_json");
|
||||
cy.get('[data-cy="app_json-title"]').should("not.exist");
|
||||
|
||||
//Import app in another workpsace
|
||||
let newWorkspaceId;
|
||||
cy.apiCreateWorkspace(data.workspaceName, data.workspaceSlug).then((res) => {
|
||||
newWorkspaceId = res.body.organization_id;
|
||||
cy.visit(data.workspaceSlug);
|
||||
|
||||
importApp(newWorkspaceId, requestData).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.message).to.include("App imported successfully into workspace");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Export App API", () => {
|
||||
const workspaceId = Cypress.env("workspaceId");
|
||||
let appId;
|
||||
importApp(workspaceId, requestData3).then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.message).to.include("App imported successfully into workspace");
|
||||
}).then(() => {
|
||||
cy.get('[data-cy^="import-export-app"]')
|
||||
.first()
|
||||
.find('[data-cy="edit-button"]')
|
||||
.click({ force: true });
|
||||
cy.skipWalkthrough();
|
||||
});
|
||||
|
||||
cy.get('[data-cy="left-sidebar-settings-button"]').click();
|
||||
cy.get('[data-cy="app-slug-input-field"]').invoke('val').then((value) => {
|
||||
appId = value;
|
||||
|
||||
//export last created version
|
||||
exportApp(workspaceId, appId, "").then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(1);
|
||||
expect(response.body.app[0].definition.appV2.appVersions[0].name).to.eq("v3");
|
||||
});
|
||||
//export specific versions
|
||||
exportApp(workspaceId, appId, "?appVersion=v2").then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(1);
|
||||
expect(response.body.app[0].definition.appV2.appVersions[0].name).to.eq("v2");
|
||||
});
|
||||
//export all versions
|
||||
exportApp(workspaceId, appId, "?exportAllVersions=true").then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body.app[0].definition.appV2.appVersions.length).to.eq(3);
|
||||
});
|
||||
|
||||
//Invalid access token and workspace
|
||||
/* exportApp(workspaceId, appId, "", {
|
||||
Authorization: "",
|
||||
"Content-Type": "application/json"
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eq(403);
|
||||
});
|
||||
|
||||
exportApp(workspaceId, appId, "", {
|
||||
Authorization: "",
|
||||
"Content-Type": "application/json"
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eq(403);
|
||||
});
|
||||
|
||||
exportApp(`${workspaceId}ee`, appId, "").then((response) => {
|
||||
expect(response.status).to.eq(400);
|
||||
});
|
||||
*/
|
||||
//with and without TJDB -x.tooljet_database
|
||||
exportApp(workspaceId, appId, "?exportTJDB=false").then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body).not.to.have.property("tooljet_database");
|
||||
});
|
||||
exportApp(workspaceId, appId, "?exportTJDB=true").then((response) => {
|
||||
expect(response.status).to.eq(201);
|
||||
expect(response.body).to.have.property("tooljet_database");
|
||||
});
|
||||
});
|
||||
//All Apps details
|
||||
allAppsDetails(workspaceId).then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
1198
cypress-tests/cypress/fixtures/templates/import_named_file.json
Normal file
1198
cypress-tests/cypress/fixtures/templates/import_named_file.json
Normal file
File diff suppressed because it is too large
Load diff
1197
cypress-tests/cypress/fixtures/templates/import_unnamed_file.json
Normal file
1197
cypress-tests/cypress/fixtures/templates/import_unnamed_file.json
Normal file
File diff suppressed because it is too large
Load diff
72
cypress-tests/cypress/support/utils/api.js
Normal file
72
cypress-tests/cypress/support/utils/api.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { groupsSelector } from "Selectors/manageGroups";
|
||||
import { navigateToManageGroups } from 'Support/utils/common';
|
||||
export const apiRequest = (method, url, body = {}, headers = {}) => {
|
||||
return cy.request({
|
||||
method,
|
||||
url,
|
||||
body,
|
||||
headers: {
|
||||
Authorization: Cypress.env('AUTH_TOKEN'),
|
||||
"Content-Type": "application/json",
|
||||
...headers,
|
||||
},
|
||||
failOnStatusCode: false
|
||||
});
|
||||
};
|
||||
|
||||
export const createUser = (userData) => {
|
||||
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/users`, userData);
|
||||
};
|
||||
|
||||
export const getUser = (userId) => {
|
||||
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/user/${userId}`);
|
||||
};
|
||||
|
||||
export const getAllUsers = () => {
|
||||
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/users`);
|
||||
};
|
||||
|
||||
export const updateUser = (userId, userData) => {
|
||||
return apiRequest("PATCH", `${Cypress.env('API_URL')}/ext/user/${userId}`, userData);
|
||||
};
|
||||
export const updateUserRole = (workspaceId, userData) => {
|
||||
return apiRequest("PUT", `${Cypress.env('API_URL')}/ext/update-user-role/workspace/${workspaceId}`, userData);
|
||||
}
|
||||
|
||||
export const replaceUserWorkspace = (userId, workspaceId, userData) => {
|
||||
return apiRequest("PATCH", `${Cypress.env('API_URL')}/ext/user/${userId}/workspace/${workspaceId}`, userData);
|
||||
}
|
||||
|
||||
export const replaceUserWorkspacesRelations = (userId, userData) => {
|
||||
return apiRequest("PUT", `${Cypress.env('API_URL')}/ext/user/${userId}/workspaces`, userData);
|
||||
}
|
||||
|
||||
export const getAllWorkspaces = () => {
|
||||
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/workspaces`);
|
||||
}
|
||||
|
||||
export const importApp = (workspaceId, appData, headers) => {
|
||||
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/import/workspace/${workspaceId}/apps`, appData, headers);
|
||||
}
|
||||
|
||||
export const exportApp = (workspaceId, appId, endpoint, headers) => {
|
||||
return apiRequest("POST", `${Cypress.env('API_URL')}/ext/export/workspace/${workspaceId}/apps/${appId}${endpoint}`, headers);
|
||||
}
|
||||
|
||||
export const allAppsDetails = (workspaceIds) => {
|
||||
return apiRequest("GET", `${Cypress.env('API_URL')}/ext/workspace/${workspaceIds}/apps`);
|
||||
}
|
||||
|
||||
export const createGroup = (groupName) => {
|
||||
cy.get(groupsSelector.createNewGroupButton).click();
|
||||
cy.clearAndType(groupsSelector.groupNameInput, groupName);
|
||||
cy.get(groupsSelector.createGroupButton).click();
|
||||
}
|
||||
export const validateUserInGroup = (email, workspaceSlug, groupName, shouldExist = true) => {
|
||||
if (workspaceSlug) cy.visit(workspaceSlug);
|
||||
navigateToManageGroups();
|
||||
cy.get(groupsSelector.groupLink(groupName)).click();
|
||||
cy.get(groupsSelector.usersLink).click();
|
||||
const userRow = `[data-cy="${email}-user-row"]`;
|
||||
cy.get(userRow).should(shouldExist ? "exist" : "not.exist");
|
||||
};
|
||||
|
|
@ -853,6 +853,9 @@ export const createGroupsAndAddUserInGroup = (groupName, email) => {
|
|||
commonSelectors.toastMessage,
|
||||
groupsText.groupCreatedToast
|
||||
);
|
||||
addUserInGroup(groupName, email);
|
||||
};
|
||||
export const addUserInGroup = (groupName, email) => {
|
||||
cy.get(groupsSelector.groupLink(groupName)).click();
|
||||
cy.clearAndType(groupsSelector.multiSelectSearchInput, email);
|
||||
cy.wait(2000);
|
||||
|
|
@ -862,7 +865,7 @@ export const createGroupsAndAddUserInGroup = (groupName, email) => {
|
|||
commonSelectors.toastMessage,
|
||||
groupsText.userAddedToast
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export const inviteUserBasedOnRole = (firstName, email, role = "end-user") => {
|
||||
fillUserInviteForm(firstName, email);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [ -f "./.env" ]; then
|
||||
export $(grep -v '^#' ./.env | xargs -d '\n') || true
|
||||
fi
|
||||
|
||||
if [ -d "./server/dist" ]; then
|
||||
SETUP_CMD='npm run db:setup:prod'
|
||||
else
|
||||
|
|
|
|||
|
|
@ -75,20 +75,39 @@ COPY --from=builder /app/server/templates ./app/server/templates
|
|||
COPY --from=builder /app/server/scripts ./app/server/scripts
|
||||
COPY --from=builder /app/server/dist ./app/server/dist
|
||||
|
||||
COPY ./docker/ce-entrypoint.sh ./app/server/entrypoint.sh
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
USER root
|
||||
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
|
||||
RUN echo "deb http://deb.debian.org/debian"
|
||||
RUN apt update && apt -y install postgresql-13 postgresql-client-13 supervisor
|
||||
USER postgres
|
||||
RUN service postgresql start && \
|
||||
psql -c "create role tooljet with login superuser password 'postgres';"
|
||||
USER root
|
||||
|
||||
# ENV defaults
|
||||
ENV TOOLJET_HOST=http://localhost:80 \
|
||||
PGRST_HOST=http://localhost:3000 \
|
||||
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
|
||||
TOOLJET_DB=tooljet_db \
|
||||
ENABLE_TOOLJET_DB=true \
|
||||
PORT=80 \
|
||||
ENV TOOLJET_HOST=http://localhost \
|
||||
NODE_ENV=production \
|
||||
LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \
|
||||
SECRET_KEY_BASE=replace_with_secret_key_base \
|
||||
ORM_LOGGING=all \
|
||||
PG_DB=tooljet_production \
|
||||
PG_USER=tooljet \
|
||||
PG_PASS=postgres \
|
||||
PG_HOST=localhost \
|
||||
ENABLE_TOOLJET_DB=true \
|
||||
TOOLJET_DB_HOST=localhost \
|
||||
TOOLJET_DB_USER=tooljet \
|
||||
TOOLJET_DB_PASS=postgres \
|
||||
TOOLJET_DB=tooljet_db \
|
||||
PGRST_HOST=http://localhost:3000 \
|
||||
PGRST_DB_URI=postgres://tooljet:postgres@localhost/tooljet_db \
|
||||
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
|
||||
PGRST_DB_PRE_CONFIG=postgrest.pre_config \
|
||||
ORM_LOGGING=true \
|
||||
DEPLOYMENT_PLATFORM=docker:local \
|
||||
HOME=/home/appuser \
|
||||
TERM=xterm
|
||||
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
|
|
|
|||
|
|
@ -104,20 +104,40 @@ COPY --from=builder /app/server/templates ./app/server/templates
|
|||
COPY --from=builder /app/server/scripts ./app/server/scripts
|
||||
COPY --from=builder /app/server/dist ./app/server/dist
|
||||
|
||||
COPY ./docker/ee/ee-entrypoint.sh ./app/server/ee-entrypoint.sh
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# ENV defaults
|
||||
ENV TOOLJET_HOST=http://localhost:80 \
|
||||
PGRST_HOST=http://localhost:3000 \
|
||||
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
|
||||
TOOLJET_DB=tooljet_db \
|
||||
ENABLE_TOOLJET_DB=true \
|
||||
PORT=80 \
|
||||
USER root
|
||||
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
||||
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list
|
||||
RUN echo "deb http://deb.debian.org/debian"
|
||||
RUN apt update && apt -y install postgresql-13 postgresql-client-13 supervisor
|
||||
USER postgres
|
||||
RUN service postgresql start && \
|
||||
psql -c "create role tooljet with login superuser password 'postgres';"
|
||||
USER root
|
||||
|
||||
# ENV defaults
|
||||
ENV TOOLJET_HOST=http://localhost \
|
||||
NODE_ENV=production \
|
||||
LOCKBOX_MASTER_KEY=replace_with_lockbox_master_key \
|
||||
SECRET_KEY_BASE=replace_with_secret_key_base \
|
||||
ORM_LOGGING=all \
|
||||
PG_DB=tooljet_production \
|
||||
PG_USER=tooljet \
|
||||
PG_PASS=postgres \
|
||||
PG_HOST=localhost \
|
||||
ENABLE_TOOLJET_DB=true \
|
||||
TOOLJET_DB_HOST=localhost \
|
||||
TOOLJET_DB_USER=tooljet \
|
||||
TOOLJET_DB_PASS=postgres \
|
||||
TOOLJET_DB=tooljet_db \
|
||||
PGRST_HOST=http://localhost:3000 \
|
||||
PGRST_DB_URI=postgres://tooljet:postgres@localhost/tooljet_db \
|
||||
PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \
|
||||
PGRST_DB_PRE_CONFIG=postgrest.pre_config \
|
||||
ORM_LOGGING=true \
|
||||
DEPLOYMENT_PLATFORM=docker:local \
|
||||
REDIS_PASS= \
|
||||
TERM=xterm
|
||||
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
service postgresql start
|
||||
|
||||
echo "
|
||||
_____ _ ___ _
|
||||
|_ _| | | |_ | | |
|
||||
|
|
|
|||
Loading…
Reference in a new issue