mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
Merge branch 'main' into release/marketplace-sprint-12
This commit is contained in:
commit
a80fc752d8
13 changed files with 121 additions and 59 deletions
|
|
@ -42,6 +42,20 @@ else
|
||||||
echo "Using external PostgREST at $PGRST_HOST."
|
echo "Using external PostgREST at $PGRST_HOST."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check WORKLOW_WORKER and skip SETUP_CMD if true
|
||||||
|
if [ "${WORKFLOW_WORKER}" == "true" ]; then
|
||||||
|
echo "WORKFLOW_WORKER is set to true. Running worker process."
|
||||||
|
npm run worker:prod
|
||||||
|
else
|
||||||
|
# Determine setup command based on the presence of ./server/dist
|
||||||
|
if [ -d "./server/dist" ]; then
|
||||||
|
SETUP_CMD='npm run db:setup:prod'
|
||||||
|
else
|
||||||
|
SETUP_CMD='npm run db:setup'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Neo4j configuration
|
# Neo4j configuration
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Default Neo4j environment values
|
# Default Neo4j environment values
|
||||||
|
|
@ -63,14 +77,14 @@ if [ -n "$NEO4J_AUTH" ]; then
|
||||||
export NEO4J_USERNAME
|
export NEO4J_USERNAME
|
||||||
export NEO4J_PASSWORD
|
export NEO4J_PASSWORD
|
||||||
|
|
||||||
echo "Neo4j authentication configured with username: $NEO4J_USERNAME"
|
echo "Neo4j authentication configured with username: $NEO4J_USERNAME" >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
echo "NEO4J_AUTH not set, using default authentication"
|
echo "NEO4J_AUTH not set, using default authentication" >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if Neo4j is already initialized and set password if necessary
|
# Check if Neo4j is already initialized and set password if necessary
|
||||||
if [ "$NEO4J_AUTH" != "none" ] && [ -n "$NEO4J_PASSWORD" ]; then
|
if [ "$NEO4J_AUTH" != "none" ] && [ -n "$NEO4J_PASSWORD" ]; then
|
||||||
echo "Setting Neo4j initial password..."
|
echo "Setting Neo4j initial password..." >/dev/null 2>&1
|
||||||
|
|
||||||
# Ensure Neo4j is not running before setting the initial password
|
# Ensure Neo4j is not running before setting the initial password
|
||||||
neo4j stop || true
|
neo4j stop || true
|
||||||
|
|
@ -78,27 +92,27 @@ if [ "$NEO4J_AUTH" != "none" ] && [ -n "$NEO4J_PASSWORD" ]; then
|
||||||
# Set the initial password using the correct command format for Neo4j 5.x
|
# Set the initial password using the correct command format for Neo4j 5.x
|
||||||
NEO4J_ADMIN_CMD=$(which neo4j-admin)
|
NEO4J_ADMIN_CMD=$(which neo4j-admin)
|
||||||
NEO4J_VERSION=$(neo4j --version | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+" | head -n 1)
|
NEO4J_VERSION=$(neo4j --version | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+" | head -n 1)
|
||||||
echo "Detected Neo4j version: $NEO4J_VERSION"
|
echo "Detected Neo4j version: $NEO4J_VERSION" >/dev/null 2>&1
|
||||||
|
|
||||||
# Use version-specific command format
|
# Use version-specific command format
|
||||||
MAJOR_VERSION=$(echo $NEO4J_VERSION | cut -d. -f1)
|
MAJOR_VERSION=$(echo $NEO4J_VERSION | cut -d. -f1)
|
||||||
if [ "$MAJOR_VERSION" -ge "5" ]; then
|
if [ "$MAJOR_VERSION" -ge "5" ]; then
|
||||||
# For Neo4j 5.x and higher
|
# For Neo4j 5.x and higher
|
||||||
echo "Using Neo4j 5.x+ password command format"
|
echo "Using Neo4j 5.x+ password command format" >/dev/null 2>&1
|
||||||
$NEO4J_ADMIN_CMD dbms set-initial-password "$NEO4J_PASSWORD" --require-password-change=false >/dev/null 2>&1 || {
|
$NEO4J_ADMIN_CMD dbms set-initial-password "$NEO4J_PASSWORD" --require-password-change=false >/dev/null 2>&1 || {
|
||||||
echo "Warning: Could not set Neo4j password, it may already be set"
|
echo "Warning: Could not set Neo4j password, it may already be set" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
# For Neo4j 4.x and lower
|
# For Neo4j 4.x and lower
|
||||||
echo "Using Neo4j 4.x password command format" >/dev/null 2>&1
|
echo "Using Neo4j 4.x password command format" >/dev/null 2>&1
|
||||||
$NEO4J_ADMIN_CMD set-initial-password "$NEO4J_PASSWORD" >/dev/null 2>&1 || {
|
$NEO4J_ADMIN_CMD set-initial-password "$NEO4J_PASSWORD" >/dev/null 2>&1 || {
|
||||||
echo "Warning: Could not set Neo4j password, it may already be set"
|
echo "Warning: Could not set Neo4j password, it may already be set" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update Neo4j configuration
|
# Update Neo4j configuration
|
||||||
echo "Configuring Neo4j..."
|
echo "Configuring Neo4j..." >/dev/null 2>&1
|
||||||
cat > /etc/neo4j/neo4j.conf << EOF
|
cat > /etc/neo4j/neo4j.conf << EOF
|
||||||
# Neo4j configuration
|
# Neo4j configuration
|
||||||
dbms.security.auth_enabled=true
|
dbms.security.auth_enabled=true
|
||||||
|
|
@ -124,12 +138,12 @@ echo "Starting Neo4j service..."
|
||||||
neo4j console >/dev/null 2>&1 &
|
neo4j console >/dev/null 2>&1 &
|
||||||
|
|
||||||
# Add a wait for Neo4j to be ready with more robust checking
|
# Add a wait for Neo4j to be ready with more robust checking
|
||||||
echo "Waiting for Neo4j to be ready..."
|
echo "Waiting for Neo4j to be ready..." >/dev/null 2>&1
|
||||||
NEO4J_READY=false
|
NEO4J_READY=false
|
||||||
for i in {1..60}; do
|
for i in {1..60}; do
|
||||||
# First try standard status check
|
# First try standard status check
|
||||||
if neo4j status >/dev/null 2>&1; then
|
if neo4j status >/dev/null 2>&1; then
|
||||||
echo "Neo4j is ready (via status check)"
|
echo "Neo4j is ready 🚀"
|
||||||
NEO4J_READY=true
|
NEO4J_READY=true
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
@ -143,7 +157,7 @@ for i in {1..60}; do
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Waiting for Neo4j to start... ($i/60)"
|
echo "Waiting for Neo4j to start... ($i/60)" >/dev/null 2>&1
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -151,19 +165,6 @@ if [ "$NEO4J_READY" = false ]; then
|
||||||
echo "WARNING: Neo4j may not be fully started yet, but continuing..."
|
echo "WARNING: Neo4j may not be fully started yet, but continuing..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check WORKLOW_WORKER and skip SETUP_CMD if true
|
|
||||||
if [ "${WORKFLOW_WORKER}" == "true" ]; then
|
|
||||||
echo "WORKFLOW_WORKER is set to true. Running worker process."
|
|
||||||
npm run worker:prod
|
|
||||||
else
|
|
||||||
# Determine setup command based on the presence of ./server/dist
|
|
||||||
if [ -d "./server/dist" ]; then
|
|
||||||
SETUP_CMD='npm run db:setup:prod'
|
|
||||||
else
|
|
||||||
SETUP_CMD='npm run db:setup'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait for PostgreSQL connection
|
# Wait for PostgreSQL connection
|
||||||
if [ -z "$DATABASE_URL" ]; then
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
./server/scripts/wait-for-it.sh $PG_HOST:${PG_PORT:-5432} --strict --timeout=300 -- echo "PostgreSQL is up"
|
./server/scripts/wait-for-it.sh $PG_HOST:${PG_PORT:-5432} --strict --timeout=300 -- echo "PostgreSQL is up"
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ COPY ./package.json ./package.json
|
||||||
COPY ./plugins/package.json ./plugins/package-lock.json ./plugins/
|
COPY ./plugins/package.json ./plugins/package-lock.json ./plugins/
|
||||||
RUN npm --prefix plugins ci --omit=dev
|
RUN npm --prefix plugins ci --omit=dev
|
||||||
COPY ./plugins/ ./plugins/
|
COPY ./plugins/ ./plugins/
|
||||||
RUN NODE_ENV=production npm --prefix plugins run build
|
RUN NODE_ENV=production npm --prefix plugins run build && npm --prefix plugins prune --omit=dev
|
||||||
RUN npm --prefix plugins prune --omit=dev
|
|
||||||
|
|
||||||
ENV TOOLJET_EDITION=ee
|
ENV TOOLJET_EDITION=ee
|
||||||
|
|
||||||
|
|
@ -52,14 +51,12 @@ ENV TOOLJET_EDITION=ee
|
||||||
COPY ./server/package.json ./server/package-lock.json ./server/
|
COPY ./server/package.json ./server/package-lock.json ./server/
|
||||||
RUN npm --prefix server ci --omit=dev
|
RUN npm --prefix server ci --omit=dev
|
||||||
COPY ./server/ ./server/
|
COPY ./server/ ./server/
|
||||||
RUN npm install -g @nestjs/cli
|
RUN npm install -g @nestjs/cli && npm install -g copyfiles
|
||||||
RUN npm install -g copyfiles
|
RUN npm --prefix server run build && npm prune --production --prefix server
|
||||||
RUN npm --prefix server run build
|
|
||||||
RUN npm prune --production --prefix server
|
|
||||||
|
|
||||||
# Install dependencies for PostgREST, curl, unzip, etc.
|
# Install dependencies for PostgREST, curl, tar, etc.
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
curl ca-certificates unzip tar \
|
curl ca-certificates tar \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ENV POSTGREST_VERSION=v12.2.0
|
ENV POSTGREST_VERSION=v12.2.0
|
||||||
|
|
@ -81,7 +78,6 @@ RUN apt-get update && \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
xz-utils \
|
xz-utils \
|
||||||
tar \
|
tar \
|
||||||
zip \
|
|
||||||
postgresql-client \
|
postgresql-client \
|
||||||
redis \
|
redis \
|
||||||
libaio1 \
|
libaio1 \
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,15 @@ export const chartConfig = {
|
||||||
displayName: 'Background color',
|
displayName: 'Background color',
|
||||||
validation: { schema: { type: 'string' }, defaultValue: 'var(--cc-surface1-surface)' },
|
validation: { schema: { type: 'string' }, defaultValue: 'var(--cc-surface1-surface)' },
|
||||||
},
|
},
|
||||||
|
borderColor: {
|
||||||
|
type: 'colorSwatches',
|
||||||
|
displayName: 'Border color',
|
||||||
|
validation: {
|
||||||
|
schema: { type: 'string' },
|
||||||
|
defaultValue: 'var(--cc-default-border)',
|
||||||
|
},
|
||||||
|
accordian: 'container',
|
||||||
|
},
|
||||||
padding: {
|
padding: {
|
||||||
type: 'code',
|
type: 'code',
|
||||||
displayName: 'Padding',
|
displayName: 'Padding',
|
||||||
|
|
@ -233,6 +242,7 @@ export const chartConfig = {
|
||||||
borderRadius: { value: '{{4}}' },
|
borderRadius: { value: '{{4}}' },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
borderColor: { value: 'var(--cc-default-border)' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { isEqual } from 'lodash';
|
||||||
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
||||||
import useStore from '@/AppBuilder/_stores/store';
|
import useStore from '@/AppBuilder/_stores/store';
|
||||||
import { shallow } from 'zustand/shallow';
|
import { shallow } from 'zustand/shallow';
|
||||||
import { getCssVarValue } from './utils';
|
import { getCssVarValue, getModifiedColor } from './utils';
|
||||||
|
|
||||||
var tinycolor = require('tinycolor2');
|
var tinycolor = require('tinycolor2');
|
||||||
|
|
||||||
|
|
@ -33,11 +33,11 @@ export const Chart = function Chart({
|
||||||
return '#fff';
|
return '#fff';
|
||||||
};
|
};
|
||||||
|
|
||||||
const { padding, visibility, disabledState, boxShadow, backgroundColor, borderRadius } = styles;
|
const { padding, visibility, disabledState, boxShadow, backgroundColor, borderRadius, borderColor } = styles;
|
||||||
const { title, markerColor, showGridLines, type, data, jsonDescription, plotFromJson, showAxes, barmode } =
|
const { title, markerColor, showGridLines, type, data, jsonDescription, plotFromJson, showAxes, barmode } =
|
||||||
properties;
|
properties;
|
||||||
|
|
||||||
const modifiedBackgroundColor = getCssVarValue(document.documentElement, backgroundColor);
|
const modifiedBackgroundColor = getModifiedColor(backgroundColor, 0);
|
||||||
const modifiedMarkerColor = getCssVarValue(document.documentElement, markerColor);
|
const modifiedMarkerColor = getCssVarValue(document.documentElement, markerColor);
|
||||||
const modifiedGridLines = getCssVarValue(document.documentElement, 'var(--cc-weak-border)');
|
const modifiedGridLines = getCssVarValue(document.documentElement, 'var(--cc-weak-border)');
|
||||||
const modifiedTextColor = getCssVarValue(document.documentElement, 'var(--cc-primary-text)');
|
const modifiedTextColor = getCssVarValue(document.documentElement, 'var(--cc-primary-text)');
|
||||||
|
|
@ -55,7 +55,8 @@ export const Chart = function Chart({
|
||||||
width: width - 4,
|
width: width - 4,
|
||||||
height,
|
height,
|
||||||
display: visibility ? '' : 'none',
|
display: visibility ? '' : 'none',
|
||||||
background: darkMode ? '#1f2936' : 'white',
|
// background: darkMode ? '#1f2936' : 'white',
|
||||||
|
border: `1px solid ${borderColor}`,
|
||||||
boxShadow,
|
boxShadow,
|
||||||
borderRadius,
|
borderRadius,
|
||||||
};
|
};
|
||||||
|
|
@ -82,6 +83,7 @@ export const Chart = function Chart({
|
||||||
? '#1f2936'
|
? '#1f2936'
|
||||||
: '#fff'
|
: '#fff'
|
||||||
: modifiedBackgroundColor;
|
: modifiedBackgroundColor;
|
||||||
|
|
||||||
const fontColor = getColor(updatedBgColor);
|
const fontColor = getColor(updatedBgColor);
|
||||||
|
|
||||||
const chartTitle = plotFromJson ? chartLayout?.title ?? title : title;
|
const chartTitle = plotFromJson ? chartLayout?.title ?? title : title;
|
||||||
|
|
@ -105,8 +107,8 @@ export const Chart = function Chart({
|
||||||
}, [JSON.stringify(chartLayout, chartTitle)]);
|
}, [JSON.stringify(chartLayout, chartTitle)]);
|
||||||
|
|
||||||
const layout = {
|
const layout = {
|
||||||
width: width - 4,
|
width: width - 6,
|
||||||
height,
|
height: height - 4,
|
||||||
plot_bgcolor: updatedBgColor,
|
plot_bgcolor: updatedBgColor,
|
||||||
paper_bgcolor: updatedBgColor,
|
paper_bgcolor: updatedBgColor,
|
||||||
title: {
|
title: {
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 80f2e4cab88aa586e9b8a731f8643bcc0cef52e7
|
Subproject commit cc864000dd03cc345e53ae9fc43821d3174f4c64
|
||||||
|
|
@ -53,6 +53,7 @@ import { SampleDBScheduler } from '@modules/data-sources/schedulers/sample-db.sc
|
||||||
import { SessionScheduler } from '@modules/session/scheduler';
|
import { SessionScheduler } from '@modules/session/scheduler';
|
||||||
import { AuditLogsClearScheduler } from '@modules/audit-logs/scheduler';
|
import { AuditLogsClearScheduler } from '@modules/audit-logs/scheduler';
|
||||||
import { ModulesModule } from '@modules/modules/module';
|
import { ModulesModule } from '@modules/modules/module';
|
||||||
|
import { EmailListenerModule } from '@modules/email-listener/module';
|
||||||
export class AppModule implements OnModuleInit {
|
export class AppModule implements OnModuleInit {
|
||||||
static async register(configs: { IS_GET_CONTEXT: boolean }): Promise<DynamicModule> {
|
static async register(configs: { IS_GET_CONTEXT: boolean }): Promise<DynamicModule> {
|
||||||
// Load static and dynamic modules
|
// Load static and dynamic modules
|
||||||
|
|
@ -113,6 +114,7 @@ export class AppModule implements OnModuleInit {
|
||||||
await AppGitModule.register(configs),
|
await AppGitModule.register(configs),
|
||||||
await CrmModule.register(configs),
|
await CrmModule.register(configs),
|
||||||
await OrganizationPaymentModule.register(configs),
|
await OrganizationPaymentModule.register(configs),
|
||||||
|
await EmailListenerModule.register(configs),
|
||||||
];
|
];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,15 @@ export const chartConfig = {
|
||||||
displayName: 'Background color',
|
displayName: 'Background color',
|
||||||
validation: { schema: { type: 'string' }, defaultValue: 'var(--cc-surface1-surface)' },
|
validation: { schema: { type: 'string' }, defaultValue: 'var(--cc-surface1-surface)' },
|
||||||
},
|
},
|
||||||
|
borderColor: {
|
||||||
|
type: 'colorSwatches',
|
||||||
|
displayName: 'Border color',
|
||||||
|
validation: {
|
||||||
|
schema: { type: 'string' },
|
||||||
|
defaultValue: 'var(--cc-default-border)',
|
||||||
|
},
|
||||||
|
accordian: 'container',
|
||||||
|
},
|
||||||
padding: {
|
padding: {
|
||||||
type: 'code',
|
type: 'code',
|
||||||
displayName: 'Padding',
|
displayName: 'Padding',
|
||||||
|
|
@ -233,6 +242,7 @@ export const chartConfig = {
|
||||||
borderRadius: { value: '{{4}}' },
|
borderRadius: { value: '{{4}}' },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
borderColor: { value: 'var(--cc-default-border)' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
import { Logger } from 'nestjs-pino';
|
import { Logger } from 'nestjs-pino';
|
||||||
import { EmailEventPayload } from './constants';
|
import { EmailEventPayload, EMAIL_EVENTS } from '@modules/email/constants';
|
||||||
import { EmailService } from '@modules/email/service';
|
import { EmailService } from '@modules/email/service';
|
||||||
import { EMAIL_EVENTS } from './constants';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EmailListener {
|
export class EmailListener {
|
||||||
|
|
@ -15,7 +14,6 @@ export class EmailListener {
|
||||||
@OnEvent('emailEvent')
|
@OnEvent('emailEvent')
|
||||||
async handleEmailEvent(eventData: EmailEventPayload) {
|
async handleEmailEvent(eventData: EmailEventPayload) {
|
||||||
const { type, payload } = eventData;
|
const { type, payload } = eventData;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case EMAIL_EVENTS.SEND_WELCOME_EMAIL:
|
case EMAIL_EVENTS.SEND_WELCOME_EMAIL:
|
||||||
17
server/src/modules/email-listener/module.ts
Normal file
17
server/src/modules/email-listener/module.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { DynamicModule } from '@nestjs/common';
|
||||||
|
import { SubModule } from '@modules/app/sub-module';
|
||||||
|
import { EmailModule } from '@modules/email/module';
|
||||||
|
import { getImportPath } from '@modules/app/constants';
|
||||||
|
|
||||||
|
export class EmailListenerModule extends SubModule {
|
||||||
|
static async register(configs?: { IS_GET_CONTEXT: boolean }): Promise<DynamicModule> {
|
||||||
|
const importPath = await getImportPath(configs?.IS_GET_CONTEXT);
|
||||||
|
const { EmailListener } = await import(`${importPath}/email-listener/listener`);
|
||||||
|
return {
|
||||||
|
module: EmailListenerModule,
|
||||||
|
imports: [await EmailModule.register(configs)],
|
||||||
|
providers: [EmailListener],
|
||||||
|
exports: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,6 @@ export class EmailModule extends SubModule {
|
||||||
const importPath = await getImportPath(configs?.IS_GET_CONTEXT);
|
const importPath = await getImportPath(configs?.IS_GET_CONTEXT);
|
||||||
const { EmailService } = await import(`${importPath}/email/service`);
|
const { EmailService } = await import(`${importPath}/email/service`);
|
||||||
const { EmailUtilService } = await import(`${importPath}/email/util.service`);
|
const { EmailUtilService } = await import(`${importPath}/email/util.service`);
|
||||||
const { EmailListener } = await import(`${importPath}/email/listener`);
|
|
||||||
return {
|
return {
|
||||||
module: EmailModule,
|
module: EmailModule,
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -18,8 +17,8 @@ export class EmailModule extends SubModule {
|
||||||
await DataSourcesModule.register(configs),
|
await DataSourcesModule.register(configs),
|
||||||
await SMTPModule.register(configs),
|
await SMTPModule.register(configs),
|
||||||
],
|
],
|
||||||
providers: [EmailService, EmailListener, EmailUtilService],
|
providers: [EmailService, EmailUtilService],
|
||||||
exports: [EmailListener, EmailUtilService],
|
exports: [EmailUtilService, EmailService],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import {
|
||||||
} from '@modules/email/dto';
|
} from '@modules/email/dto';
|
||||||
import { EmailUtilService } from './util.service';
|
import { EmailUtilService } from './util.service';
|
||||||
import { IEmailService } from './interfaces/IService';
|
import { IEmailService } from './interfaces/IService';
|
||||||
import { INSTANCE_SYSTEM_SETTINGS } from '@modules/instance-settings/constants';
|
|
||||||
import { WhiteLabellingUtilService } from '@modules/white-labelling/util.service';
|
import { WhiteLabellingUtilService } from '@modules/white-labelling/util.service';
|
||||||
|
|
||||||
handlebars.registerHelper('capitalize', function (value) {
|
handlebars.registerHelper('capitalize', function (value) {
|
||||||
|
|
@ -29,15 +28,6 @@ export class EmailService implements IEmailService {
|
||||||
protected WHITE_LABEL_TEXT;
|
protected WHITE_LABEL_TEXT;
|
||||||
protected WHITE_LABEL_LOGO;
|
protected WHITE_LABEL_LOGO;
|
||||||
protected SUB_PATH;
|
protected SUB_PATH;
|
||||||
protected SMTP: {
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_ENABLED]: boolean;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_DOMAIN]: string;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_PORT]: string;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_USERNAME]: string;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_PASSWORD]: string;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_FROM_EMAIL]: string;
|
|
||||||
[INSTANCE_SYSTEM_SETTINGS.SMTP_ENV_CONFIGURED]: boolean;
|
|
||||||
};
|
|
||||||
protected defaultWhiteLabelState: boolean;
|
protected defaultWhiteLabelState: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -63,14 +53,13 @@ export class EmailService implements IEmailService {
|
||||||
|
|
||||||
async init(organizationId?: string | null) {
|
async init(organizationId?: string | null) {
|
||||||
const whiteLabelSettings = await this.emailUtilService.retrieveWhiteLabelSettings(null);
|
const whiteLabelSettings = await this.emailUtilService.retrieveWhiteLabelSettings(null);
|
||||||
this.SMTP = await this.emailUtilService.retrieveSmtpSettings();
|
|
||||||
this.WHITE_LABEL_TEXT = whiteLabelSettings?.white_label_text;
|
this.WHITE_LABEL_TEXT = whiteLabelSettings?.white_label_text;
|
||||||
this.WHITE_LABEL_LOGO = whiteLabelSettings?.white_label_logo;
|
this.WHITE_LABEL_LOGO = whiteLabelSettings?.white_label_logo;
|
||||||
this.defaultWhiteLabelState = whiteLabelSettings?.default;
|
this.defaultWhiteLabelState = whiteLabelSettings?.default;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected compileTemplate(templatePath: string, templateData: object) {
|
protected compileTemplate(templatePath: string, templateData: object) {
|
||||||
this.emailUtilService.compileTemplate(templatePath, templateData);
|
return this.emailUtilService.compileTemplate(templatePath, templateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected stripTrailingSlash(hostname: string) {
|
protected stripTrailingSlash(hostname: string) {
|
||||||
|
|
@ -88,6 +77,7 @@ export class EmailService implements IEmailService {
|
||||||
redirectTo,
|
redirectTo,
|
||||||
} = payload;
|
} = payload;
|
||||||
await this.init(organizationId);
|
await this.init(organizationId);
|
||||||
|
await this.emailUtilService.init(organizationId);
|
||||||
const isOrgInvite = organizationInvitationToken && sender && organizationName;
|
const isOrgInvite = organizationInvitationToken && sender && organizationName;
|
||||||
const inviteUrl = generateInviteURL(invitationtoken, organizationInvitationToken, organizationId, null, redirectTo);
|
const inviteUrl = generateInviteURL(invitationtoken, organizationInvitationToken, organizationId, null, redirectTo);
|
||||||
const subject = isOrgInvite ? `Welcome to ${organizationName || 'ToolJet'}` : 'Set up your account!';
|
const subject = isOrgInvite ? `Welcome to ${organizationName || 'ToolJet'}` : 'Set up your account!';
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,11 @@ export class EmailUtilService implements IEmailUtilService {
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly whiteLabellingUtilService: WhiteLabellingUtilService,
|
protected readonly whiteLabellingUtilService: WhiteLabellingUtilService,
|
||||||
protected readonly smtpUtilService: SMTPUtilService
|
protected readonly smtpUtilService: SMTPUtilService
|
||||||
) {}
|
) {
|
||||||
|
this.TOOLJET_HOST = this.stripTrailingSlash(process.env.TOOLJET_HOST);
|
||||||
|
this.SUB_PATH = process.env.SUB_PATH;
|
||||||
|
this.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
}
|
||||||
|
|
||||||
async retrieveWhiteLabelSettings(organizationId?: string | null): Promise<any> {
|
async retrieveWhiteLabelSettings(organizationId?: string | null): Promise<any> {
|
||||||
const whiteLabelSetting = await this.whiteLabellingUtilService.getProcessedSettings(organizationId);
|
const whiteLabelSetting = await this.whiteLabellingUtilService.getProcessedSettings(organizationId);
|
||||||
|
|
@ -253,4 +257,14 @@ export class EmailUtilService implements IEmailUtilService {
|
||||||
whiteLabelLogo: DEFAULT_WHITE_LABELLING_SETTINGS.white_label_logo,
|
whiteLabelLogo: DEFAULT_WHITE_LABELLING_SETTINGS.white_label_logo,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
protected stripTrailingSlash(hostname: string) {
|
||||||
|
return hostname?.endsWith('/') ? hostname.slice(0, -1) : hostname;
|
||||||
|
}
|
||||||
|
async init(organizationId?: string | null) {
|
||||||
|
const whiteLabelSettings = await this.retrieveWhiteLabelSettings(null);
|
||||||
|
this.SMTP = await this.retrieveSmtpSettings();
|
||||||
|
this.WHITE_LABEL_TEXT = whiteLabelSettings?.white_label_text;
|
||||||
|
this.WHITE_LABEL_LOGO = whiteLabelSettings?.white_label_logo;
|
||||||
|
this.defaultWhiteLabelState = whiteLabelSettings?.default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,29 @@ export class LicenseCountsService implements ILicenseCountsService {
|
||||||
manager
|
manager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
async getUserIdWithEndUserRole(manager: EntityManager): Promise<string[]> {
|
||||||
|
const statusList = [WORKSPACE_USER_STATUS.INVITED, WORKSPACE_USER_STATUS.ACTIVE];
|
||||||
|
|
||||||
|
const users = await manager.find(User, {
|
||||||
|
select: ['id'],
|
||||||
|
where: {
|
||||||
|
status: Not(USER_STATUS.ARCHIVED),
|
||||||
|
organizationUsers: {
|
||||||
|
status: In(statusList),
|
||||||
|
},
|
||||||
|
userPermissions: {
|
||||||
|
name: USER_ROLE.END_USER,
|
||||||
|
organization: {
|
||||||
|
status: WORKSPACE_STATUS.ACTIVE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
relations: ['organizationUsers', 'userPermissions', 'userPermissions.organization'],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Extract unique user IDs
|
||||||
|
return [...new Set(users.map((user) => user.id))];
|
||||||
|
}
|
||||||
|
|
||||||
async fetchTotalAppCount(organizationId: string, manager: EntityManager): Promise<number> {
|
async fetchTotalAppCount(organizationId: string, manager: EntityManager): Promise<number> {
|
||||||
if (getTooljetEdition() !== TOOLJET_EDITIONS.Cloud) {
|
if (getTooljetEdition() !== TOOLJET_EDITIONS.Cloud) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue