Merge branch 'dlt_inspector_as_submodule' into dlt_export_existing_transactions_drizzleOrm
15
.github/workflows/test_backend.yml
vendored
@ -93,18 +93,3 @@ jobs:
|
|||||||
|
|
||||||
- name: Backend | Typecheck
|
- name: Backend | Typecheck
|
||||||
run: turbo backend#typecheck backend#build
|
run: turbo backend#typecheck backend#build
|
||||||
|
|
||||||
locales:
|
|
||||||
if: needs.files-changed.outputs.backend == 'true'
|
|
||||||
name: Locales - Backend
|
|
||||||
needs: files-changed
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: install bun
|
|
||||||
uses: oven-sh/setup-bun@v2
|
|
||||||
|
|
||||||
- name: Backend | Locales
|
|
||||||
run: cd backend && bun locales
|
|
||||||
15
.github/workflows/test_core.yml
vendored
@ -43,3 +43,18 @@ jobs:
|
|||||||
- name: typecheck && unit test
|
- name: typecheck && unit test
|
||||||
run: turbo core#test core#typecheck
|
run: turbo core#test core#typecheck
|
||||||
|
|
||||||
|
locales:
|
||||||
|
if: needs.files-changed.outputs.core == 'true'
|
||||||
|
name: Locales - Core
|
||||||
|
needs: files-changed
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: install bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Core | Locales
|
||||||
|
run: cd core && bun locales
|
||||||
|
|
||||||
|
|||||||
13
CHANGELOG.md
@ -4,9 +4,18 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||||||
|
|
||||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||||
|
|
||||||
#### [v2.7.0](https://github.com/gradido/gradido/compare/v2.7.0...v2.7.0)
|
#### [v2.7.1](https://github.com/gradido/gradido/compare/v2.7.0...v2.7.1)
|
||||||
|
|
||||||
- fixes [`414ff8a`](https://github.com/gradido/gradido/commit/414ff8ac5a7477109f80123ccca5c4c8ed4511b2)
|
- feat(frontend): new startpage images [`#3576`](https://github.com/gradido/gradido/pull/3576)
|
||||||
|
- feat(frontend): update login subtitle [`#3574`](https://github.com/gradido/gradido/pull/3574)
|
||||||
|
- feat(frontend): update copy symbol and change link order [`#3575`](https://github.com/gradido/gradido/pull/3575)
|
||||||
|
- fix(backend): correct seeding [`#3572`](https://github.com/gradido/gradido/pull/3572)
|
||||||
|
- feat(dlt): dlt-connector takes care of gradido node [`#3568`](https://github.com/gradido/gradido/pull/3568)
|
||||||
|
- refactor(dlt): upgrade dlt for using gradido blockchain lib and hiero [`#3551`](https://github.com/gradido/gradido/pull/3551)
|
||||||
|
- chore(release): v2.7.0 [`#3557`](https://github.com/gradido/gradido/pull/3557)
|
||||||
|
- feat(federation): use own table for handshake state [`#3555`](https://github.com/gradido/gradido/pull/3555)
|
||||||
|
- fix(workflow): use bun instead of yarn [`#3550`](https://github.com/gradido/gradido/pull/3550)
|
||||||
|
- feat(workflow): adjust for new bun version [`#3554`](https://github.com/gradido/gradido/pull/3554)
|
||||||
|
|
||||||
#### [v2.7.0](https://github.com/gradido/gradido/compare/2.6.1...v2.7.0)
|
#### [v2.7.0](https://github.com/gradido/gradido/compare/2.6.1...v2.7.0)
|
||||||
|
|
||||||
|
|||||||
@ -189,11 +189,11 @@ describe('test', () => {
|
|||||||
```ts
|
```ts
|
||||||
import { clearLogs, printLogs } from 'config-schema/test/testSetup'
|
import { clearLogs, printLogs } from 'config-schema/test/testSetup'
|
||||||
```
|
```
|
||||||
- vitest (frontend, admin, database):
|
- vitest (frontend, admin):
|
||||||
```ts
|
```ts
|
||||||
import { clearLogs, printLogs } from 'config-schema/test/testSetup.vitest'
|
import { clearLogs, printLogs } from 'config-schema/test/testSetup.vitest'
|
||||||
```
|
```
|
||||||
- bun (shared, core):
|
- bun (shared, core, database):
|
||||||
```ts
|
```ts
|
||||||
import { clearLogs, printLogs } from 'config-schema/test/testSetup.bun'
|
import { clearLogs, printLogs } from 'config-schema/test/testSetup.bun'
|
||||||
```
|
```
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
"description": "Administration Interface for Gradido",
|
"description": "Administration Interface for Gradido",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "Gradido Academy - https://www.gradido.net",
|
"author": "Gradido Academy - https://www.gradido.net",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -22,7 +22,7 @@ KLICKTIPP_APIKEY_DE=SomeFakeKeyDE
|
|||||||
KLICKTIPP_APIKEY_EN=SomeFakeKeyEN
|
KLICKTIPP_APIKEY_EN=SomeFakeKeyEN
|
||||||
|
|
||||||
# DltConnector
|
# DltConnector
|
||||||
DLT_CONNECTOR=true
|
DLT_ACTIVE=false
|
||||||
DLT_CONNECTOR_URL=http://localhost:6010
|
DLT_CONNECTOR_URL=http://localhost:6010
|
||||||
|
|
||||||
# Community
|
# Community
|
||||||
|
|||||||
@ -1,77 +0,0 @@
|
|||||||
# Server
|
|
||||||
PORT=4000
|
|
||||||
JWT_SECRET=secret123
|
|
||||||
JWT_EXPIRES_IN=10m
|
|
||||||
GRAPHIQL=false
|
|
||||||
GDT_API_URL=https://gdt.gradido.net
|
|
||||||
|
|
||||||
# Database
|
|
||||||
DB_HOST=127.0.0.1
|
|
||||||
DB_PORT=3306
|
|
||||||
DB_USER=root
|
|
||||||
DB_PASSWORD=
|
|
||||||
DB_DATABASE=gradido_community
|
|
||||||
TYPEORM_LOGGING_RELATIVE_PATH=typeorm.backend.log
|
|
||||||
|
|
||||||
# Klicktipp
|
|
||||||
KLICKTIPP=false
|
|
||||||
KLICKTTIPP_API_URL=https://api.klicktipp.com
|
|
||||||
KLICKTIPP_USER=gradido_test
|
|
||||||
KLICKTIPP_PASSWORD=secret321
|
|
||||||
KLICKTIPP_APIKEY_DE=SomeFakeKeyDE
|
|
||||||
KLICKTIPP_APIKEY_EN=SomeFakeKeyEN
|
|
||||||
|
|
||||||
# DltConnector
|
|
||||||
DLT_CONNECTOR=true
|
|
||||||
DLT_CONNECTOR_URL=http://localhost:6010
|
|
||||||
|
|
||||||
# Community
|
|
||||||
COMMUNITY_NAME=Gradido Entwicklung
|
|
||||||
COMMUNITY_URL=http://localhost
|
|
||||||
COMMUNITY_REGISTER_PATH=/register
|
|
||||||
COMMUNITY_REDEEM_PATH=/redeem/{code}
|
|
||||||
COMMUNITY_REDEEM_CONTRIBUTION_PATH=/redeem/CL-{code}
|
|
||||||
COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido.
|
|
||||||
COMMUNITY_SUPPORT_MAIL=support@supportmail.com
|
|
||||||
|
|
||||||
# Login Server
|
|
||||||
LOGIN_APP_SECRET=21ffbbc616fe
|
|
||||||
LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a
|
|
||||||
|
|
||||||
# EMail
|
|
||||||
EMAIL=false
|
|
||||||
EMAIL_TEST_MODUS=false
|
|
||||||
EMAIL_TEST_RECEIVER=stage1@gradido.net
|
|
||||||
EMAIL_USERNAME=gradido_email
|
|
||||||
EMAIL_SENDER=info@gradido.net
|
|
||||||
EMAIL_PASSWORD=xxx
|
|
||||||
EMAIL_SMTP_HOST=gmail.com
|
|
||||||
EMAIL_SMTP_PORT=587
|
|
||||||
EMAIL_LINK_VERIFICATION_PATH=/checkEmail/{optin}{code}
|
|
||||||
EMAIL_LINK_SETPASSWORD_PATH=/reset-password/{optin}
|
|
||||||
EMAIL_LINK_FORGOTPASSWORD_PATH=/forgot-password
|
|
||||||
EMAIL_LINK_OVERVIEW_PATH=/overview
|
|
||||||
EMAIL_CODE_VALID_TIME=1440
|
|
||||||
EMAIL_CODE_REQUEST_TIME=10
|
|
||||||
|
|
||||||
# Webhook
|
|
||||||
WEBHOOK_ELOPAGE_SECRET=secret
|
|
||||||
|
|
||||||
# SET LOG LEVEL AS NEEDED IN YOUR .ENV
|
|
||||||
# POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal
|
|
||||||
LOG_LEVEL=INFO
|
|
||||||
|
|
||||||
# Federation
|
|
||||||
FEDERATION_VALIDATE_COMMUNITY_TIMER=60000
|
|
||||||
|
|
||||||
# GMS
|
|
||||||
# GMS_ACTIVE=true
|
|
||||||
# Coordinates of Illuminz test instance
|
|
||||||
#GMS_API_URL=http://54.176.169.179:3071
|
|
||||||
GMS_API_URL=http://localhost:4044
|
|
||||||
GMS_DASHBOARD_URL=http://localhost:8080
|
|
||||||
|
|
||||||
# HUMHUB
|
|
||||||
HUMHUB_ACTIVE=true
|
|
||||||
HUMHUB_API_URL=https://community-test.gradido.net
|
|
||||||
HUMHUB_JWT_KEY=GwdkIKi-rkRS0mXC4Cg3MYc3ktZh89VFmntDpNKET_dUfcIdjL_957F3nCv3brNtDfbbV81NViKaktUsfExrkH
|
|
||||||
@ -24,7 +24,7 @@ KLICKTIPP_APIKEY_DE=$KLICKTIPP_APIKEY_DE
|
|||||||
KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN
|
KLICKTIPP_APIKEY_EN=$KLICKTIPP_APIKEY_EN
|
||||||
|
|
||||||
# DltConnector
|
# DltConnector
|
||||||
DLT_CONNECTOR=$DLT_CONNECTOR
|
DLT_ACTIVE=$DLT_ACTIVE
|
||||||
DLT_CONNECTOR_PORT=$DLT_CONNECTOR_PORT
|
DLT_CONNECTOR_PORT=$DLT_CONNECTOR_PORT
|
||||||
|
|
||||||
# Community
|
# Community
|
||||||
|
|||||||
@ -114,8 +114,7 @@ COPY --chown=app:app --from=build ${DOCKER_WORKDIR}/backend/build/worker.js ./wo
|
|||||||
# add node_modules from production_node_modules
|
# add node_modules from production_node_modules
|
||||||
COPY --chown=app:app --from=production-node-modules ${DOCKER_WORKDIR}/node_modules ./node_modules
|
COPY --chown=app:app --from=production-node-modules ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||||
|
|
||||||
# Copy locales
|
COPY --chown=app:app --from=build ${DOCKER_WORKDIR}/core/build/templates ./templates
|
||||||
COPY --chown=app:app --from=build ${DOCKER_WORKDIR}/backend/locales ./locales
|
|
||||||
|
|
||||||
# Run command
|
# Run command
|
||||||
CMD ["node", "index.js"]
|
CMD ["node", "index.js"]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "backend",
|
"name": "backend",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
||||||
"repository": "https://github.com/gradido/gradido/backend",
|
"repository": "https://github.com/gradido/gradido/backend",
|
||||||
@ -8,7 +8,7 @@
|
|||||||
"author": "Gradido Academy - https://www.gradido.net",
|
"author": "Gradido Academy - https://www.gradido.net",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "ts-node ./esbuild.config.ts && mkdirp build/templates/ && ncp src/emails/templates build/templates && mkdirp locales/ && ncp src/locales locales",
|
"build": "ts-node ./esbuild.config.ts && mkdirp build/templates/ && ncp ../core/build/templates build/templates",
|
||||||
"dev": "cross-env TZ=UTC nodemon -w src --ext ts,pug,json,css -r tsconfig-paths/register src/index.ts",
|
"dev": "cross-env TZ=UTC nodemon -w src --ext ts,pug,json,css -r tsconfig-paths/register src/index.ts",
|
||||||
"test": "cross-env TZ=UTC NODE_ENV=development DB_DATABASE=gradido_test_backend jest --runInBand --forceExit --detectOpenHandles",
|
"test": "cross-env TZ=UTC NODE_ENV=development DB_DATABASE=gradido_test_backend jest --runInBand --forceExit --detectOpenHandles",
|
||||||
"test:coverage": "cross-env TZ=UTC NODE_ENV=development DB_DATABASE=gradido_test_backend jest --coverage --runInBand --forceExit --detectOpenHandles",
|
"test:coverage": "cross-env TZ=UTC NODE_ENV=development DB_DATABASE=gradido_test_backend jest --coverage --runInBand --forceExit --detectOpenHandles",
|
||||||
@ -19,8 +19,6 @@
|
|||||||
"lint": "biome check --error-on-warnings .",
|
"lint": "biome check --error-on-warnings .",
|
||||||
"lint:fix": "biome check --error-on-warnings . --write",
|
"lint:fix": "biome check --error-on-warnings . --write",
|
||||||
"lint:fix:unsafe": "biome check --fix --unsafe",
|
"lint:fix:unsafe": "biome check --fix --unsafe",
|
||||||
"locales": "scripts/sort.sh",
|
|
||||||
"locales:fix": "scripts/sort.sh --fix",
|
|
||||||
"start": "cross-env TZ=UTC node build/index.js",
|
"start": "cross-env TZ=UTC node build/index.js",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"clear": "rm -rf node_modules && rm -rf build && rm -rf .turbo"
|
"clear": "rm -rf node_modules && rm -rf build && rm -rf .turbo"
|
||||||
@ -49,7 +47,6 @@
|
|||||||
"@types/jest": "27.0.2",
|
"@types/jest": "27.0.2",
|
||||||
"@types/lodash.clonedeep": "^4.5.6",
|
"@types/lodash.clonedeep": "^4.5.6",
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "^17.0.21",
|
||||||
"@types/nodemailer": "^6.4.4",
|
|
||||||
"@types/sodium-native": "^2.3.5",
|
"@types/sodium-native": "^2.3.5",
|
||||||
"@types/source-map-support": "^0.5.10",
|
"@types/source-map-support": "^0.5.10",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
@ -83,11 +80,9 @@
|
|||||||
"log4js": "^6.7.1",
|
"log4js": "^6.7.1",
|
||||||
"mkdirp": "^3.0.1",
|
"mkdirp": "^3.0.1",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"nodemailer": "^6.6.5",
|
|
||||||
"nodemon": "^2.0.7",
|
"nodemon": "^2.0.7",
|
||||||
"openai": "^4.87.3",
|
"openai": "^4.87.3",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"pug": "^3.0.2",
|
|
||||||
"random-bigint": "^0.0.1",
|
"random-bigint": "^0.0.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"regenerator-runtime": "^0.14.1",
|
"regenerator-runtime": "^0.14.1",
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
def walk(f):
|
|
||||||
. as $in
|
|
||||||
| if type == "object" then
|
|
||||||
reduce keys_unsorted[] as $key
|
|
||||||
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
|
|
||||||
elif type == "array" then map( walk(f) ) | f
|
|
||||||
else f
|
|
||||||
end;
|
|
||||||
|
|
||||||
def keys_sort_by(f):
|
|
||||||
to_entries | sort_by(.key|f ) | from_entries;
|
|
||||||
|
|
||||||
walk(if type == "object" then keys_sort_by(ascii_upcase) else . end)
|
|
||||||
@ -5,17 +5,17 @@ import { DltConnectorClient } from './DltConnectorClient'
|
|||||||
describe('undefined DltConnectorClient', () => {
|
describe('undefined DltConnectorClient', () => {
|
||||||
it('invalid url', () => {
|
it('invalid url', () => {
|
||||||
CONFIG.DLT_CONNECTOR_URL = ''
|
CONFIG.DLT_CONNECTOR_URL = ''
|
||||||
CONFIG.DLT_CONNECTOR = true
|
CONFIG.DLT_ACTIVE = true
|
||||||
const result = DltConnectorClient.getInstance()
|
const result = DltConnectorClient.getInstance()
|
||||||
expect(result).toBeUndefined()
|
expect(result).toBeUndefined()
|
||||||
CONFIG.DLT_CONNECTOR_URL = 'http://dlt-connector:6010'
|
CONFIG.DLT_CONNECTOR_URL = 'http://dlt-connector:6010'
|
||||||
})
|
})
|
||||||
|
|
||||||
it('DLT_CONNECTOR is false', () => {
|
it('DLT_ACTIVE is false', () => {
|
||||||
CONFIG.DLT_CONNECTOR = false
|
CONFIG.DLT_ACTIVE = false
|
||||||
const result = DltConnectorClient.getInstance()
|
const result = DltConnectorClient.getInstance()
|
||||||
expect(result).toBeUndefined()
|
expect(result).toBeUndefined()
|
||||||
CONFIG.DLT_CONNECTOR = true
|
CONFIG.DLT_ACTIVE = true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export class DltConnectorClient {
|
|||||||
* just one instance of each subclass around.
|
* just one instance of each subclass around.
|
||||||
*/
|
*/
|
||||||
public static getInstance(): DltConnectorClient | undefined {
|
public static getInstance(): DltConnectorClient | undefined {
|
||||||
if (!CONFIG.DLT_CONNECTOR || !CONFIG.DLT_CONNECTOR_URL) {
|
if (!CONFIG.DLT_ACTIVE || !CONFIG.DLT_CONNECTOR_URL) {
|
||||||
logger.info(`dlt-connector are disabled via config...`)
|
logger.info(`dlt-connector are disabled via config...`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export class DltConnectorClient {
|
|||||||
* just one instance of each subclass around.
|
* just one instance of each subclass around.
|
||||||
*/
|
*/
|
||||||
public static getInstance(): DltConnectorClient | undefined {
|
public static getInstance(): DltConnectorClient | undefined {
|
||||||
if (!CONFIG.DLT_CONNECTOR || !CONFIG.DLT_CONNECTOR_URL) {
|
if (!CONFIG.DLT_ACTIVE || !CONFIG.DLT_CONNECTOR_URL) {
|
||||||
logger.info(`dlt-connector are disabled via config...`)
|
logger.info(`dlt-connector are disabled via config...`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ async function executeDltTransaction(draft: TransactionDraft | null, typeId: Dlt
|
|||||||
* and update dltTransactionId of transaction in db with hiero transaction id
|
* and update dltTransactionId of transaction in db with hiero transaction id
|
||||||
*/
|
*/
|
||||||
export async function registerAddressTransaction(user: DbUser, community: DbCommunity): Promise<DbDltTransaction | null> {
|
export async function registerAddressTransaction(user: DbUser, community: DbCommunity): Promise<DbDltTransaction | null> {
|
||||||
if (!CONFIG.DLT_CONNECTOR) {
|
if (!CONFIG.DLT_ACTIVE) {
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
if (!user.id) {
|
if (!user.id) {
|
||||||
@ -90,7 +90,7 @@ export async function contributionTransaction(
|
|||||||
signingUser: DbUser,
|
signingUser: DbUser,
|
||||||
createdAt: Date,
|
createdAt: Date,
|
||||||
): Promise<DbDltTransaction | null> {
|
): Promise<DbDltTransaction | null> {
|
||||||
if (!CONFIG.DLT_CONNECTOR) {
|
if (!CONFIG.DLT_ACTIVE) {
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
const homeCommunity = await getHomeCommunity()
|
const homeCommunity = await getHomeCommunity()
|
||||||
@ -109,7 +109,7 @@ export async function transferTransaction(
|
|||||||
memo: string,
|
memo: string,
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
): Promise<DbDltTransaction | null> {
|
): Promise<DbDltTransaction | null> {
|
||||||
if (!CONFIG.DLT_CONNECTOR) {
|
if (!CONFIG.DLT_ACTIVE) {
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
// load community if not already loaded, maybe they are remote communities
|
// load community if not already loaded, maybe they are remote communities
|
||||||
@ -127,7 +127,7 @@ export async function transferTransaction(
|
|||||||
|
|
||||||
export async function deferredTransferTransaction(senderUser: DbUser, transactionLink: DbTransactionLink)
|
export async function deferredTransferTransaction(senderUser: DbUser, transactionLink: DbTransactionLink)
|
||||||
: Promise<DbDltTransaction | null> {
|
: Promise<DbDltTransaction | null> {
|
||||||
if (!CONFIG.DLT_CONNECTOR) {
|
if (!CONFIG.DLT_ACTIVE) {
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
// load community if not already loaded
|
// load community if not already loaded
|
||||||
@ -140,7 +140,7 @@ export async function deferredTransferTransaction(senderUser: DbUser, transactio
|
|||||||
|
|
||||||
export async function redeemDeferredTransferTransaction(transactionLink: DbTransactionLink, amount: string, createdAt: Date, recipientUser: DbUser)
|
export async function redeemDeferredTransferTransaction(transactionLink: DbTransactionLink, amount: string, createdAt: Date, recipientUser: DbUser)
|
||||||
: Promise<DbDltTransaction | null> {
|
: Promise<DbDltTransaction | null> {
|
||||||
if (!CONFIG.DLT_CONNECTOR) {
|
if (!CONFIG.DLT_ACTIVE) {
|
||||||
return Promise.resolve(null)
|
return Promise.resolve(null)
|
||||||
}
|
}
|
||||||
// load user and communities if not already loaded
|
// load user and communities if not already loaded
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { User as DbUser } from 'database'
|
|||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
// import { createGmsUser } from '@/apis/gms/GmsClient'
|
// import { createGmsUser } from '@/apis/gms/GmsClient'
|
||||||
// import { GmsUser } from '@/apis/gms/model/GmsUser'
|
// import { GmsUser } from '@/apis/gms/model/GmsUser'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { sendUserToGms } from '@/graphql/resolver/util/sendUserToGms'
|
import { sendUserToGms } from '@/graphql/resolver/util/sendUserToGms'
|
||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
import { initLogging } from '@/server/logger'
|
import { initLogging } from '@/server/logger'
|
||||||
@ -13,7 +13,7 @@ import { getLogger } from 'log4js'
|
|||||||
|
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.gms.ExportUsers`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.apis.gms.ExportUsers`)
|
||||||
|
|
||||||
CONFIG.EMAIL = false
|
CORE_CONFIG.EMAIL = false
|
||||||
// use force to copy over all user even if gmsRegistered is set to true
|
// use force to copy over all user even if gmsRegistered is set to true
|
||||||
const forceMode = process.argv.includes('--force')
|
const forceMode = process.argv.includes('--force')
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,7 @@ export class OpenaiClient {
|
|||||||
if (openaiThreadEntity.updatedAt < new Date(Date.now() - OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS * 24 * 60 * 60 * 1000)) {
|
if (openaiThreadEntity.updatedAt < new Date(Date.now() - OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS * 24 * 60 * 60 * 1000)) {
|
||||||
logger.info(`Openai thread for user: ${user.id} is older than ${OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS} days, deleting...`)
|
logger.info(`Openai thread for user: ${user.id} is older than ${OPENAI_AI_THREAD_DEFAULT_TIMEOUT_DAYS} days, deleting...`)
|
||||||
// let run async, because it could need some time, but we don't need to wait, because we create a new one nevertheless
|
// let run async, because it could need some time, but we don't need to wait, because we create a new one nevertheless
|
||||||
|
// biome-ignore lint/complexity/noVoid: start it intentionally async without waiting for result
|
||||||
void this.deleteThread(openaiThreadEntity.id)
|
void this.deleteThread(openaiThreadEntity.id)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ const logging = {
|
|||||||
|
|
||||||
const server = {
|
const server = {
|
||||||
BACKEND_PORT: process.env.BACKEND_PORT ?? 4000,
|
BACKEND_PORT: process.env.BACKEND_PORT ?? 4000,
|
||||||
|
DLT_ACTIVE: process.env.DLT_ACTIVE === 'true' || false,
|
||||||
JWT_SECRET: process.env.JWT_SECRET ?? 'secret123',
|
JWT_SECRET: process.env.JWT_SECRET ?? 'secret123',
|
||||||
JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN ?? '10m',
|
JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN ?? '10m',
|
||||||
REDEEM_JWT_TOKEN_EXPIRATION: process.env.REDEEM_JWT_TOKEN_EXPIRATION ?? '10m',
|
REDEEM_JWT_TOKEN_EXPIRATION: process.env.REDEEM_JWT_TOKEN_EXPIRATION ?? '10m',
|
||||||
@ -41,9 +42,7 @@ const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNIT
|
|||||||
const DLT_CONNECTOR_PORT = process.env.DLT_CONNECTOR_PORT ?? 6010
|
const DLT_CONNECTOR_PORT = process.env.DLT_CONNECTOR_PORT ?? 6010
|
||||||
|
|
||||||
const dltConnector = {
|
const dltConnector = {
|
||||||
DLT_CONNECTOR: process.env.DLT_CONNECTOR === 'true' || false,
|
|
||||||
DLT_CONNECTOR_URL: process.env.DLT_CONNECTOR_URL ?? `${COMMUNITY_URL}:${DLT_CONNECTOR_PORT}`,
|
DLT_CONNECTOR_URL: process.env.DLT_CONNECTOR_URL ?? `${COMMUNITY_URL}:${DLT_CONNECTOR_PORT}`,
|
||||||
DLT_GRADIDO_NODE_SERVER_HOME_FOLDER: process.env.DLT_GRADIDO_NODE_SERVER_HOME_FOLDER ?? '~/.gradido',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const community = {
|
const community = {
|
||||||
@ -64,22 +63,10 @@ const loginServer = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const email = {
|
const email = {
|
||||||
EMAIL: process.env.EMAIL === 'true',
|
|
||||||
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true',
|
|
||||||
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER ?? 'stage1@gradido.net',
|
|
||||||
EMAIL_USERNAME: process.env.EMAIL_USERNAME ?? '',
|
|
||||||
EMAIL_SENDER: process.env.EMAIL_SENDER ?? 'info@gradido.net',
|
|
||||||
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD ?? '',
|
|
||||||
EMAIL_SMTP_HOST: process.env.EMAIL_SMTP_HOST ?? 'mailserver',
|
|
||||||
EMAIL_SMTP_PORT: Number(process.env.EMAIL_SMTP_PORT) || 1025,
|
|
||||||
|
|
||||||
EMAIL_TLS: process.env.EMAIL_TLS !== 'false',
|
|
||||||
EMAIL_LINK_VERIFICATION:
|
EMAIL_LINK_VERIFICATION:
|
||||||
COMMUNITY_URL + (process.env.EMAIL_LINK_VERIFICATION_PATH ?? '/checkEmail/'),
|
COMMUNITY_URL + (process.env.EMAIL_LINK_VERIFICATION_PATH ?? '/checkEmail/'),
|
||||||
EMAIL_LINK_SETPASSWORD:
|
EMAIL_LINK_SETPASSWORD:
|
||||||
COMMUNITY_URL + (process.env.EMAIL_LINK_SETPASSWORD_PATH ?? '/reset-password/'),
|
COMMUNITY_URL + (process.env.EMAIL_LINK_SETPASSWORD_PATH ?? '/reset-password/'),
|
||||||
EMAIL_LINK_FORGOTPASSWORD:
|
|
||||||
COMMUNITY_URL + (process.env.EMAIL_LINK_FORGOTPASSWORD_PATH ?? '/forgot-password'),
|
|
||||||
EMAIL_LINK_OVERVIEW: COMMUNITY_URL + (process.env.EMAIL_LINK_OVERVIEW_PATH ?? '/overview'),
|
EMAIL_LINK_OVERVIEW: COMMUNITY_URL + (process.env.EMAIL_LINK_OVERVIEW_PATH ?? '/overview'),
|
||||||
// time in minutes a optin code is valid
|
// time in minutes a optin code is valid
|
||||||
EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME
|
EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
COMMUNITY_SUPPORT_MAIL,
|
COMMUNITY_SUPPORT_MAIL,
|
||||||
COMMUNITY_URL,
|
COMMUNITY_URL,
|
||||||
DECAY_START_TIME,
|
DECAY_START_TIME,
|
||||||
|
DLT_ACTIVE,
|
||||||
GDT_ACTIVE,
|
GDT_ACTIVE,
|
||||||
GDT_API_URL,
|
GDT_API_URL,
|
||||||
GMS_ACTIVE,
|
GMS_ACTIVE,
|
||||||
@ -27,6 +28,7 @@ export const schema = Joi.object({
|
|||||||
COMMUNITY_DESCRIPTION,
|
COMMUNITY_DESCRIPTION,
|
||||||
COMMUNITY_SUPPORT_MAIL,
|
COMMUNITY_SUPPORT_MAIL,
|
||||||
DECAY_START_TIME,
|
DECAY_START_TIME,
|
||||||
|
DLT_ACTIVE,
|
||||||
GDT_API_URL,
|
GDT_API_URL,
|
||||||
GDT_ACTIVE,
|
GDT_ACTIVE,
|
||||||
GMS_ACTIVE,
|
GMS_ACTIVE,
|
||||||
@ -68,90 +70,11 @@ export const schema = Joi.object({
|
|||||||
.default('http://0.0.0.0/redeem/CL-')
|
.default('http://0.0.0.0/redeem/CL-')
|
||||||
.required(),
|
.required(),
|
||||||
|
|
||||||
DLT_CONNECTOR: Joi.boolean()
|
|
||||||
.description('Flag to indicate if DLT-Connector is used. (Still in development)')
|
|
||||||
.default(false)
|
|
||||||
.required(),
|
|
||||||
|
|
||||||
DLT_CONNECTOR_URL: Joi.string()
|
DLT_CONNECTOR_URL: Joi.string()
|
||||||
.uri({ scheme: ['http', 'https'] })
|
.uri({ scheme: ['http', 'https'] })
|
||||||
.default('http://localhost:6010')
|
.default('http://localhost:6010')
|
||||||
.when('DLT_CONNECTOR', { is: true, then: Joi.required() })
|
.when('DLT_ACTIVE', { is: true, then: Joi.required() })
|
||||||
.description('The URL for GDT API endpoint'),
|
.description('The URL for DLT connector'),
|
||||||
|
|
||||||
DLT_GRADIDO_NODE_SERVER_HOME_FOLDER: Joi.string()
|
|
||||||
.default('~/.gradido')
|
|
||||||
.description('The home folder for the gradido dlt node server'),
|
|
||||||
|
|
||||||
EMAIL: Joi.boolean()
|
|
||||||
.default(false)
|
|
||||||
.description('Enable or disable email functionality')
|
|
||||||
.required(),
|
|
||||||
|
|
||||||
EMAIL_TEST_MODUS: Joi.boolean()
|
|
||||||
.default(false)
|
|
||||||
.description('When enabled, all emails are sended to EMAIL_TEST_RECEIVER')
|
|
||||||
.optional(),
|
|
||||||
|
|
||||||
EMAIL_TEST_RECEIVER: Joi.string()
|
|
||||||
.email()
|
|
||||||
.default('stage1@gradido.net')
|
|
||||||
.when('EMAIL_TEST_MODUS', { is: true, then: Joi.required() })
|
|
||||||
.description('Email address used in test mode'),
|
|
||||||
|
|
||||||
EMAIL_USERNAME: Joi.alternatives().conditional(Joi.ref('EMAIL'), {
|
|
||||||
is: true,
|
|
||||||
then: Joi.alternatives().conditional(Joi.ref('NODE_ENV'), {
|
|
||||||
is: 'development',
|
|
||||||
then: Joi.string()
|
|
||||||
.allow('')
|
|
||||||
.description('Username for SMTP authentication (optional in development)'),
|
|
||||||
otherwise: Joi.string()
|
|
||||||
.pattern(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)
|
|
||||||
.description('Valid SMTP username required in production')
|
|
||||||
.required(),
|
|
||||||
}),
|
|
||||||
otherwise: Joi.string().allow('').optional(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
EMAIL_SENDER: Joi.string()
|
|
||||||
.email()
|
|
||||||
.when('EMAIL', { is: true, then: Joi.required() })
|
|
||||||
.default('info@gradido.net')
|
|
||||||
.description('Email address used as sender'),
|
|
||||||
|
|
||||||
EMAIL_PASSWORD: Joi.alternatives().conditional(Joi.ref('EMAIL'), {
|
|
||||||
is: true,
|
|
||||||
then: Joi.alternatives().conditional(Joi.ref('NODE_ENV'), {
|
|
||||||
is: 'development',
|
|
||||||
then: Joi.string()
|
|
||||||
.allow('')
|
|
||||||
.description('Password for SMTP authentication (optional in development)'),
|
|
||||||
otherwise: Joi.string()
|
|
||||||
.min(8)
|
|
||||||
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#]).{8,}$/)
|
|
||||||
.description(
|
|
||||||
'Password must be at least 8 characters long, include uppercase and lowercase letters, a number, and a special character',
|
|
||||||
)
|
|
||||||
.required(),
|
|
||||||
}),
|
|
||||||
otherwise: Joi.string().allow('').optional(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
EMAIL_SMTP_HOST: Joi.string()
|
|
||||||
.hostname()
|
|
||||||
.when('EMAIL', { is: true, then: Joi.required() })
|
|
||||||
.default('mailserver')
|
|
||||||
.description('SMTP server hostname'),
|
|
||||||
|
|
||||||
EMAIL_SMTP_PORT: Joi.number()
|
|
||||||
.integer()
|
|
||||||
.positive()
|
|
||||||
.when('EMAIL', { is: true, then: Joi.required() })
|
|
||||||
.default(1025)
|
|
||||||
.description('SMTP server port'),
|
|
||||||
|
|
||||||
EMAIL_TLS: Joi.boolean().default(true).description('Enable or disable TLS for SMTP').optional(),
|
|
||||||
|
|
||||||
EMAIL_LINK_VERIFICATION: Joi.string()
|
EMAIL_LINK_VERIFICATION: Joi.string()
|
||||||
.uri({ scheme: ['http', 'https'] })
|
.uri({ scheme: ['http', 'https'] })
|
||||||
@ -175,17 +98,6 @@ export const schema = Joi.object({
|
|||||||
.description('Email Verification link for set initial Password.')
|
.description('Email Verification link for set initial Password.')
|
||||||
.required(),
|
.required(),
|
||||||
|
|
||||||
EMAIL_LINK_FORGOTPASSWORD: Joi.string()
|
|
||||||
.uri({ scheme: ['http', 'https'] })
|
|
||||||
.custom((value: string, helpers: Joi.CustomHelpers<string>): string | Joi.ErrorReport => {
|
|
||||||
if (!value.startsWith(helpers.state.ancestors[0].COMMUNITY_URL)) {
|
|
||||||
return helpers.error('string.pattern.base', { value, communityUrl: COMMUNITY_URL })
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
})
|
|
||||||
.description('Email Verification link for set new Password, when old Password was forgotten.')
|
|
||||||
.required(),
|
|
||||||
|
|
||||||
EMAIL_LINK_OVERVIEW: Joi.string()
|
EMAIL_LINK_OVERVIEW: Joi.string()
|
||||||
.uri({ scheme: ['http', 'https'] })
|
.uri({ scheme: ['http', 'https'] })
|
||||||
.custom((value: string, helpers: Joi.CustomHelpers<string>): string | Joi.ErrorReport => {
|
.custom((value: string, helpers: Joi.CustomHelpers<string>): string | Joi.ErrorReport => {
|
||||||
@ -213,7 +125,7 @@ export const schema = Joi.object({
|
|||||||
.description('Time in minutes before a new code can be requested')
|
.description('Time in minutes before a new code can be requested')
|
||||||
.required(),
|
.required(),
|
||||||
|
|
||||||
FEDERATION_VALIDATE_COMMUNITY_TIMER: Joi.number()
|
FEDERATION_VALIDATE_COMMUNITY_TIMER: Joi.number()
|
||||||
.integer()
|
.integer()
|
||||||
.min(1000)
|
.min(1000)
|
||||||
.default(60000)
|
.default(60000)
|
||||||
|
|||||||
@ -1,225 +0,0 @@
|
|||||||
import { Decimal } from 'decimal.js-light'
|
|
||||||
|
|
||||||
import { CONFIG } from '@/config'
|
|
||||||
import { decimalSeparatorByLanguage } from 'core'
|
|
||||||
|
|
||||||
import { sendEmailTranslated } from './sendEmailTranslated'
|
|
||||||
|
|
||||||
export interface ContributionEmailCommonData {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
senderFirstName: string
|
|
||||||
senderLastName: string
|
|
||||||
contributionMemo: string
|
|
||||||
contributionFrontendLink: string
|
|
||||||
}
|
|
||||||
|
|
||||||
function toContributionEmailLocales(data: ContributionEmailCommonData): Record<string, unknown> {
|
|
||||||
return {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
senderFirstName: data.senderFirstName,
|
|
||||||
senderLastName: data.senderLastName,
|
|
||||||
contributionMemo: data.contributionMemo,
|
|
||||||
contributionFrontendLink: data.contributionFrontendLink,
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendAddedContributionMessageEmail = (
|
|
||||||
data: ContributionEmailCommonData & {
|
|
||||||
message: string
|
|
||||||
},
|
|
||||||
): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: {
|
|
||||||
to: `${data.firstName} ${data.lastName} <${data.email}>`,
|
|
||||||
},
|
|
||||||
template: 'addedContributionMessage',
|
|
||||||
locals: {
|
|
||||||
...toContributionEmailLocales(data),
|
|
||||||
message: data.message,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendAccountActivationEmail = (data: {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
activationLink: string
|
|
||||||
timeDurationObject: Record<string, unknown>
|
|
||||||
logoUrl?: string | null
|
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'accountActivation',
|
|
||||||
locals: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
activationLink: data.activationLink,
|
|
||||||
timeDurationObject: data.timeDurationObject,
|
|
||||||
logoUrl: data.logoUrl,
|
|
||||||
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendAccountMultiRegistrationEmail = (data: {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'accountMultiRegistration',
|
|
||||||
locals: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendContributionConfirmedEmail = (
|
|
||||||
data: ContributionEmailCommonData & {
|
|
||||||
contributionAmount: Decimal
|
|
||||||
},
|
|
||||||
): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'contributionConfirmed',
|
|
||||||
locals: {
|
|
||||||
...toContributionEmailLocales(data),
|
|
||||||
contributionAmount: decimalSeparatorByLanguage(data.contributionAmount, data.language),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendContributionChangedByModeratorEmail = (
|
|
||||||
data: ContributionEmailCommonData & {
|
|
||||||
contributionMemoUpdated: string
|
|
||||||
},
|
|
||||||
): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'contributionChangedByModerator',
|
|
||||||
locals: {
|
|
||||||
...toContributionEmailLocales(data),
|
|
||||||
contributionMemoUpdated: data.contributionMemoUpdated,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendContributionDeletedEmail = (
|
|
||||||
data: ContributionEmailCommonData,
|
|
||||||
): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'contributionDeleted',
|
|
||||||
locals: toContributionEmailLocales(data),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendContributionDeniedEmail = (
|
|
||||||
data: ContributionEmailCommonData,
|
|
||||||
): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'contributionDenied',
|
|
||||||
locals: toContributionEmailLocales(data),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendResetPasswordEmail = (data: {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
resetLink: string
|
|
||||||
timeDurationObject: Record<string, unknown>
|
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'resetPassword',
|
|
||||||
locals: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
resetLink: data.resetLink,
|
|
||||||
timeDurationObject: data.timeDurationObject,
|
|
||||||
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendTransactionLinkRedeemedEmail = (data: {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
senderFirstName: string
|
|
||||||
senderLastName: string
|
|
||||||
senderEmail: string
|
|
||||||
transactionMemo: string
|
|
||||||
transactionAmount: Decimal
|
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'transactionLinkRedeemed',
|
|
||||||
locals: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
senderFirstName: data.senderFirstName,
|
|
||||||
senderLastName: data.senderLastName,
|
|
||||||
senderEmail: data.senderEmail,
|
|
||||||
transactionMemo: data.transactionMemo,
|
|
||||||
transactionAmount: decimalSeparatorByLanguage(data.transactionAmount, data.language),
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const sendTransactionReceivedEmail = (data: {
|
|
||||||
firstName: string
|
|
||||||
lastName: string
|
|
||||||
email: string
|
|
||||||
language: string
|
|
||||||
senderFirstName: string
|
|
||||||
senderLastName: string
|
|
||||||
senderEmail: string
|
|
||||||
memo: string
|
|
||||||
transactionAmount: Decimal
|
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
|
||||||
return sendEmailTranslated({
|
|
||||||
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
|
||||||
template: 'transactionReceived',
|
|
||||||
locals: {
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
locale: data.language,
|
|
||||||
memo: data.memo,
|
|
||||||
senderFirstName: data.senderFirstName,
|
|
||||||
senderLastName: data.senderLastName,
|
|
||||||
senderEmail: data.senderEmail,
|
|
||||||
transactionAmount: decimalSeparatorByLanguage(data.transactionAmount, data.language),
|
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -5,7 +5,6 @@ import { DataSource } from 'typeorm'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import { cleanDB, testEnvironment } from '@test/helpers'
|
import { cleanDB, testEnvironment } from '@test/helpers'
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
|
|
||||||
import { userFactory } from '@/seeds/factory/user'
|
import { userFactory } from '@/seeds/factory/user'
|
||||||
import { login, updateHomeCommunityQuery } from '@/seeds/graphql/mutations'
|
import { login, updateHomeCommunityQuery } from '@/seeds/graphql/mutations'
|
||||||
@ -43,7 +42,7 @@ const peterLoginData = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment(getLogger('apollo'), localization)
|
testEnv = await testEnvironment(getLogger('apollo'))
|
||||||
mutate = testEnv.mutate
|
mutate = testEnv.mutate
|
||||||
query = testEnv.query
|
query = testEnv.query
|
||||||
con = testEnv.con
|
con = testEnv.con
|
||||||
|
|||||||
@ -5,10 +5,9 @@ import { DataSource } from 'typeorm'
|
|||||||
|
|
||||||
import { ContributionStatus } from '@enum/ContributionStatus'
|
import { ContributionStatus } from '@enum/ContributionStatus'
|
||||||
import { cleanDB, resetToken, testEnvironment } from '@test/helpers'
|
import { cleanDB, resetToken, testEnvironment } from '@test/helpers'
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants'
|
import { sendAddedContributionMessageEmail } from 'core'
|
||||||
import { EventType } from '@/event/Events'
|
import { EventType } from '@/event/Events'
|
||||||
import { userFactory } from '@/seeds/factory/user'
|
import { userFactory } from '@/seeds/factory/user'
|
||||||
import {
|
import {
|
||||||
@ -30,14 +29,12 @@ const interactionLogger = getLogger(
|
|||||||
)
|
)
|
||||||
|
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
jest.mock('@/emails/sendEmailVariants', () => {
|
jest.mock('core', () => {
|
||||||
const originalModule = jest.requireActual('@/emails/sendEmailVariants')
|
const originalModule = jest.requireActual('core')
|
||||||
return {
|
return {
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
...originalModule,
|
...originalModule,
|
||||||
sendAddedContributionMessageEmail: jest.fn((a) =>
|
sendAddedContributionMessageEmail: jest.fn(),
|
||||||
originalModule.sendAddedContributionMessageEmail(a),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -51,7 +48,7 @@ let testEnv: {
|
|||||||
let result: any
|
let result: any
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment(logger, localization)
|
testEnv = await testEnvironment(logger)
|
||||||
mutate = testEnv.mutate
|
mutate = testEnv.mutate
|
||||||
con = testEnv.con
|
con = testEnv.con
|
||||||
await cleanDB()
|
await cleanDB()
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { Order } from '@enum/Order'
|
|||||||
import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage'
|
import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage'
|
||||||
|
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants'
|
import { sendAddedContributionMessageEmail } from 'core'
|
||||||
import {
|
import {
|
||||||
EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE,
|
EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE,
|
||||||
EVENT_CONTRIBUTION_MESSAGE_CREATE,
|
EVENT_CONTRIBUTION_MESSAGE_CREATE,
|
||||||
|
|||||||
@ -14,14 +14,13 @@ import {
|
|||||||
resetToken,
|
resetToken,
|
||||||
testEnvironment,
|
testEnvironment,
|
||||||
} from '@test/helpers'
|
} from '@test/helpers'
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
import {
|
import {
|
||||||
sendContributionConfirmedEmail,
|
sendContributionConfirmedEmail,
|
||||||
sendContributionDeletedEmail,
|
sendContributionDeletedEmail,
|
||||||
sendContributionDeniedEmail,
|
sendContributionDeniedEmail,
|
||||||
} from '@/emails/sendEmailVariants'
|
} from 'core'
|
||||||
import { EventType } from '@/event/Events'
|
import { EventType } from '@/event/Events'
|
||||||
import { creations } from '@/seeds/creation/index'
|
import { creations } from '@/seeds/creation/index'
|
||||||
import { creationFactory } from '@/seeds/factory/creation'
|
import { creationFactory } from '@/seeds/factory/creation'
|
||||||
@ -54,7 +53,17 @@ import { getFirstDayOfPreviousNMonth } from 'core'
|
|||||||
import { getLogger } from 'config-schema/test/testSetup'
|
import { getLogger } from 'config-schema/test/testSetup'
|
||||||
import { getLogger as originalGetLogger } from 'log4js'
|
import { getLogger as originalGetLogger } from 'log4js'
|
||||||
|
|
||||||
jest.mock('@/emails/sendEmailVariants')
|
jest.mock('core', () => {
|
||||||
|
const originalModule = jest.requireActual('core')
|
||||||
|
return {
|
||||||
|
__esModule: true,
|
||||||
|
...originalModule,
|
||||||
|
sendContributionDeniedEmail: jest.fn(),
|
||||||
|
sendContributionConfirmedEmail: jest.fn(),
|
||||||
|
sendContributionDeletedEmail: jest.fn(),
|
||||||
|
sendEmailTranslated: jest.fn(),
|
||||||
|
}
|
||||||
|
})
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
|
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
|
||||||
@ -77,7 +86,7 @@ let contributionToDelete: any
|
|||||||
let bibiCreatedContribution: Contribution
|
let bibiCreatedContribution: Contribution
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment(originalGetLogger('apollo'), localization)
|
testEnv = await testEnvironment(originalGetLogger('apollo'))
|
||||||
mutate = testEnv.mutate
|
mutate = testEnv.mutate
|
||||||
query = testEnv.query
|
query = testEnv.query
|
||||||
con = testEnv.con
|
con = testEnv.con
|
||||||
|
|||||||
@ -21,15 +21,15 @@ import { AdminUpdateContribution } from '@model/AdminUpdateContribution'
|
|||||||
import { Contribution, ContributionListResult } from '@model/Contribution'
|
import { Contribution, ContributionListResult } from '@model/Contribution'
|
||||||
import { OpenCreation } from '@model/OpenCreation'
|
import { OpenCreation } from '@model/OpenCreation'
|
||||||
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
|
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
|
||||||
import { TransactionTypeId } from 'core'
|
|
||||||
|
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import {
|
import {
|
||||||
|
fullName,
|
||||||
sendContributionChangedByModeratorEmail,
|
sendContributionChangedByModeratorEmail,
|
||||||
sendContributionConfirmedEmail,
|
sendContributionConfirmedEmail,
|
||||||
sendContributionDeletedEmail,
|
sendContributionDeletedEmail,
|
||||||
sendContributionDeniedEmail,
|
sendContributionDeniedEmail,
|
||||||
} from '@/emails/sendEmailVariants'
|
TransactionTypeId
|
||||||
|
} from 'core'
|
||||||
import {
|
import {
|
||||||
EVENT_ADMIN_CONTRIBUTION_CONFIRM,
|
EVENT_ADMIN_CONTRIBUTION_CONFIRM,
|
||||||
EVENT_ADMIN_CONTRIBUTION_CREATE,
|
EVENT_ADMIN_CONTRIBUTION_CREATE,
|
||||||
@ -44,7 +44,6 @@ import { UpdateUnconfirmedContributionContext } from '@/interactions/updateUncon
|
|||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
|
import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
|
||||||
import { TRANSACTIONS_LOCK } from 'database'
|
import { TRANSACTIONS_LOCK } from 'database'
|
||||||
import { fullName } from 'core'
|
|
||||||
import { calculateDecay, Decay } from 'shared'
|
import { calculateDecay, Decay } from 'shared'
|
||||||
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { DataSource } from 'typeorm'
|
|||||||
|
|
||||||
import { cleanDB, testEnvironment } from '@test/helpers'
|
import { cleanDB, testEnvironment } from '@test/helpers'
|
||||||
|
|
||||||
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import { writeHomeCommunityEntry } from '@/seeds/community'
|
import { writeHomeCommunityEntry } from '@/seeds/community'
|
||||||
import { createUser, forgotPassword, setPassword } from '@/seeds/graphql/mutations'
|
import { createUser, forgotPassword, setPassword } from '@/seeds/graphql/mutations'
|
||||||
@ -21,7 +22,7 @@ let testEnv: {
|
|||||||
|
|
||||||
CONFIG.EMAIL_CODE_VALID_TIME = 1440
|
CONFIG.EMAIL_CODE_VALID_TIME = 1440
|
||||||
CONFIG.EMAIL_CODE_REQUEST_TIME = 10
|
CONFIG.EMAIL_CODE_REQUEST_TIME = 10
|
||||||
CONFIG.EMAIL = false
|
CORE_CONFIG.EMAIL = false
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment()
|
testEnv = await testEnvironment()
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { Event as DbEvent, UserContact } from 'database'
|
|||||||
import { GraphQLError } from 'graphql'
|
import { GraphQLError } from 'graphql'
|
||||||
|
|
||||||
import { cleanDB, resetToken, testEnvironment } from '@test/helpers'
|
import { cleanDB, resetToken, testEnvironment } from '@test/helpers'
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
import { getLogger } from 'config-schema/test/testSetup'
|
import { getLogger } from 'config-schema/test/testSetup'
|
||||||
|
|
||||||
import { EventType } from '@/event/Events'
|
import { EventType } from '@/event/Events'
|
||||||
@ -20,7 +19,7 @@ let mutate: any
|
|||||||
let con: any
|
let con: any
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment(logger, localization)
|
testEnv = await testEnvironment(logger)
|
||||||
mutate = testEnv.mutate
|
mutate = testEnv.mutate
|
||||||
con = testEnv.con
|
con = testEnv.con
|
||||||
await cleanDB()
|
await cleanDB()
|
||||||
|
|||||||
@ -43,7 +43,7 @@ const logErrorLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
|
|||||||
|
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
|
|
||||||
CONFIG.DLT_CONNECTOR = false
|
CONFIG.DLT_ACTIVE = false
|
||||||
|
|
||||||
// mock semaphore to allow use fake timers
|
// mock semaphore to allow use fake timers
|
||||||
jest.mock('database/src/util/TRANSACTIONS_LOCK')
|
jest.mock('database/src/util/TRANSACTIONS_LOCK')
|
||||||
|
|||||||
@ -34,12 +34,13 @@ import { peterLustig } from '@/seeds/users/peter-lustig'
|
|||||||
import { stephenHawking } from '@/seeds/users/stephen-hawking'
|
import { stephenHawking } from '@/seeds/users/stephen-hawking'
|
||||||
import { getLogger } from 'config-schema/test/testSetup'
|
import { getLogger } from 'config-schema/test/testSetup'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
import { CONFIG as CORE_CONFIG} from 'core'
|
||||||
|
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
|
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.LogError`)
|
||||||
CONFIG.DLT_CONNECTOR = false
|
CONFIG.DLT_ACTIVE = false
|
||||||
CONFIG.EMAIL = false
|
CORE_CONFIG.EMAIL = false
|
||||||
|
|
||||||
let mutate: ApolloServerTestClient['mutate']
|
let mutate: ApolloServerTestClient['mutate']
|
||||||
let query: ApolloServerTestClient['query']
|
let query: ApolloServerTestClient['query']
|
||||||
@ -72,7 +73,6 @@ let peter: User
|
|||||||
|
|
||||||
let homeCom: DbCommunity
|
let homeCom: DbCommunity
|
||||||
let foreignCom: DbCommunity
|
let foreignCom: DbCommunity
|
||||||
let fedForeignCom: DbFederatedCommunity
|
|
||||||
|
|
||||||
describe('send coins', () => {
|
describe('send coins', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
AppDatabase,
|
AppDatabase,
|
||||||
countOpenPendingTransactions,
|
countOpenPendingTransactions,
|
||||||
Community as DbCommunity,
|
|
||||||
DltTransaction as DbDltTransaction,
|
DltTransaction as DbDltTransaction,
|
||||||
Transaction as dbTransaction,
|
Transaction as dbTransaction,
|
||||||
TransactionLink as dbTransactionLink,
|
TransactionLink as dbTransactionLink,
|
||||||
User as dbUser,
|
User as dbUser,
|
||||||
findUserByIdentifier,
|
findUserByIdentifier,
|
||||||
TransactionLoggingView,
|
|
||||||
UserLoggingView
|
|
||||||
} from 'database'
|
} from 'database'
|
||||||
import { Decimal } from 'decimal.js-light'
|
import { Decimal } from 'decimal.js-light'
|
||||||
import { Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql'
|
import { Args, Authorized, Ctx, Mutation, Query, Resolver } from 'type-graphql'
|
||||||
@ -20,21 +17,22 @@ import { Order } from '@enum/Order'
|
|||||||
import { Transaction } from '@model/Transaction'
|
import { Transaction } from '@model/Transaction'
|
||||||
import { TransactionList } from '@model/TransactionList'
|
import { TransactionList } from '@model/TransactionList'
|
||||||
import { User } from '@model/User'
|
import { User } from '@model/User'
|
||||||
import { processXComCompleteTransaction, TransactionTypeId } from 'core'
|
import {
|
||||||
|
fullName,
|
||||||
|
processXComCompleteTransaction,
|
||||||
|
sendTransactionLinkRedeemedEmail,
|
||||||
|
sendTransactionReceivedEmail,
|
||||||
|
TransactionTypeId
|
||||||
|
} from 'core'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import {
|
import {
|
||||||
sendTransactionLinkRedeemedEmail,
|
EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
|
||||||
sendTransactionReceivedEmail,
|
|
||||||
} from '@/emails/sendEmailVariants'
|
|
||||||
import { EVENT_TRANSACTION_RECEIVE, EVENT_TRANSACTION_SEND } from '@/event/Events'
|
|
||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
import { Context, getUser } from '@/server/context'
|
import { Context, getUser } from '@/server/context'
|
||||||
import { communityUser } from '@/util/communityUser'
|
import { communityUser } from '@/util/communityUser'
|
||||||
import { calculateBalance } from '@/util/validate'
|
import { calculateBalance } from '@/util/validate'
|
||||||
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
|
import { virtualDecayTransaction, virtualLinkTransaction } from '@/util/virtualTransactions'
|
||||||
import { fullName } from 'core'
|
|
||||||
import { TRANSACTIONS_LOCK } from 'database'
|
import { TRANSACTIONS_LOCK } from 'database'
|
||||||
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import { UserContactType } from '@enum/UserContactType'
|
|||||||
import { ContributionLink } from '@model/ContributionLink'
|
import { ContributionLink } from '@model/ContributionLink'
|
||||||
import { Location } from '@model/Location'
|
import { Location } from '@model/Location'
|
||||||
import { cleanDB, headerPushMock, resetToken, testEnvironment } from '@test/helpers'
|
import { cleanDB, headerPushMock, resetToken, testEnvironment } from '@test/helpers'
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
|
|
||||||
import { subscribe } from '@/apis/KlicktippController'
|
import { subscribe } from '@/apis/KlicktippController'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
@ -28,7 +27,7 @@ import {
|
|||||||
sendAccountActivationEmail,
|
sendAccountActivationEmail,
|
||||||
sendAccountMultiRegistrationEmail,
|
sendAccountMultiRegistrationEmail,
|
||||||
sendResetPasswordEmail,
|
sendResetPasswordEmail,
|
||||||
} from '@/emails/sendEmailVariants'
|
} from 'core'
|
||||||
import { EventType } from '@/event/Events'
|
import { EventType } from '@/event/Events'
|
||||||
import { PublishNameType } from '@/graphql/enum/PublishNameType'
|
import { PublishNameType } from '@/graphql/enum/PublishNameType'
|
||||||
import { SecretKeyCryptographyCreateKey } from '@/password/EncryptorUtils'
|
import { SecretKeyCryptographyCreateKey } from '@/password/EncryptorUtils'
|
||||||
@ -74,16 +73,15 @@ import { Location2Point } from './util/Location2Point'
|
|||||||
jest.mock('@/apis/humhub/HumHubClient')
|
jest.mock('@/apis/humhub/HumHubClient')
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
|
|
||||||
jest.mock('@/emails/sendEmailVariants', () => {
|
jest.mock('core', () => {
|
||||||
const originalModule = jest.requireActual('@/emails/sendEmailVariants')
|
const originalModule = jest.requireActual('core')
|
||||||
return {
|
return {
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
...originalModule,
|
...originalModule,
|
||||||
sendAccountActivationEmail: jest.fn((a) => originalModule.sendAccountActivationEmail(a)),
|
sendAccountActivationEmail: jest.fn(),
|
||||||
sendAccountMultiRegistrationEmail: jest.fn((a) =>
|
sendAccountMultiRegistrationEmail: jest.fn(),
|
||||||
originalModule.sendAccountMultiRegistrationEmail(a),
|
sendResetPasswordEmail: jest.fn(),
|
||||||
),
|
sendEmailTranslated: jest.fn(),
|
||||||
sendResetPasswordEmail: jest.fn((a) => originalModule.sendResetPasswordEmail(a)),
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -112,12 +110,12 @@ let testEnv: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
testEnv = await testEnvironment(getLogger('apollo'), localization)
|
testEnv = await testEnvironment(getLogger('apollo'))
|
||||||
mutate = testEnv.mutate
|
mutate = testEnv.mutate
|
||||||
query = testEnv.query
|
query = testEnv.query
|
||||||
con = testEnv.con
|
con = testEnv.con
|
||||||
CONFIG.HUMHUB_ACTIVE = false
|
CONFIG.HUMHUB_ACTIVE = false
|
||||||
CONFIG.DLT_CONNECTOR = false
|
CONFIG.DLT_ACTIVE = false
|
||||||
await cleanDB()
|
await cleanDB()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -155,6 +153,7 @@ describe('UserResolver', () => {
|
|||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({ data: { createUser: { id: expect.any(Number) } } }),
|
expect.objectContaining({ data: { createUser: { id: expect.any(Number) } } }),
|
||||||
)
|
)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('valid input data', () => {
|
describe('valid input data', () => {
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import {
|
|||||||
findUserByIdentifier
|
findUserByIdentifier
|
||||||
} from 'database'
|
} from 'database'
|
||||||
import { GraphQLResolveInfo } from 'graphql'
|
import { GraphQLResolveInfo } from 'graphql'
|
||||||
import i18n from 'i18n'
|
|
||||||
import {
|
import {
|
||||||
Arg,
|
Arg,
|
||||||
Args,
|
Args,
|
||||||
@ -57,11 +56,6 @@ import { encode } from '@/auth/JWT'
|
|||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import { PublishNameLogic } from '@/data/PublishName.logic'
|
import { PublishNameLogic } from '@/data/PublishName.logic'
|
||||||
import {
|
|
||||||
sendAccountActivationEmail,
|
|
||||||
sendAccountMultiRegistrationEmail,
|
|
||||||
sendResetPasswordEmail,
|
|
||||||
} from '@/emails/sendEmailVariants'
|
|
||||||
import {
|
import {
|
||||||
EVENT_ADMIN_USER_DELETE,
|
EVENT_ADMIN_USER_DELETE,
|
||||||
EVENT_ADMIN_USER_ROLE_SET,
|
EVENT_ADMIN_USER_ROLE_SET,
|
||||||
@ -85,8 +79,12 @@ import { Context, getClientTimezoneOffset, getUser } from '@/server/context'
|
|||||||
import { communityDbUser } from '@/util/communityUser'
|
import { communityDbUser } from '@/util/communityUser'
|
||||||
import { hasElopageBuys } from '@/util/hasElopageBuys'
|
import { hasElopageBuys } from '@/util/hasElopageBuys'
|
||||||
import { durationInMinutesFromDates, getTimeDurationObject, printTimeDuration } from '@/util/time'
|
import { durationInMinutesFromDates, getTimeDurationObject, printTimeDuration } from '@/util/time'
|
||||||
import { delay } from 'core'
|
import {
|
||||||
|
delay,
|
||||||
|
sendAccountActivationEmail,
|
||||||
|
sendAccountMultiRegistrationEmail,
|
||||||
|
sendResetPasswordEmail,
|
||||||
|
} from 'core'
|
||||||
import random from 'random-bigint'
|
import random from 'random-bigint'
|
||||||
import { randombytes_random } from 'sodium-native'
|
import { randombytes_random } from 'sodium-native'
|
||||||
|
|
||||||
@ -233,7 +231,6 @@ export class UserResolver {
|
|||||||
logger.debug('validation of login credentials successful...')
|
logger.debug('validation of login credentials successful...')
|
||||||
|
|
||||||
const user = new User(dbUser)
|
const user = new User(dbUser)
|
||||||
i18n.setLocale(user.language)
|
|
||||||
|
|
||||||
// Elopage Status & Stored PublisherId
|
// Elopage Status & Stored PublisherId
|
||||||
user.hasElopage = await this.hasElopage({ ...context, user: dbUser })
|
user.hasElopage = await this.hasElopage({ ...context, user: dbUser })
|
||||||
@ -322,7 +319,6 @@ export class UserResolver {
|
|||||||
if (!language || !isLanguage(language)) {
|
if (!language || !isLanguage(language)) {
|
||||||
language = DEFAULT_LANGUAGE
|
language = DEFAULT_LANGUAGE
|
||||||
}
|
}
|
||||||
i18n.setLocale(language)
|
|
||||||
|
|
||||||
// check if user with email still exists?
|
// check if user with email still exists?
|
||||||
email = email.trim().toLowerCase()
|
email = email.trim().toLowerCase()
|
||||||
@ -764,7 +760,6 @@ export class UserResolver {
|
|||||||
throw new LogError('Given language is not a valid language or not supported')
|
throw new LogError('Given language is not a valid language or not supported')
|
||||||
}
|
}
|
||||||
user.language = language
|
user.language = language
|
||||||
i18n.setLocale(language)
|
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,12 +22,13 @@ import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
|
|||||||
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
|
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
|
||||||
import { peterLustig } from '@/seeds/users/peter-lustig'
|
import { peterLustig } from '@/seeds/users/peter-lustig'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { TRANSACTIONS_LOCK } from 'database'
|
import { TRANSACTIONS_LOCK } from 'database'
|
||||||
|
|
||||||
jest.mock('@/password/EncryptorUtils')
|
jest.mock('@/password/EncryptorUtils')
|
||||||
|
|
||||||
CONFIG.DLT_CONNECTOR = false
|
CONFIG.DLT_ACTIVE = false
|
||||||
CONFIG.EMAIL = false
|
CORE_CONFIG.EMAIL = false
|
||||||
|
|
||||||
let mutate: ApolloServerTestClient['mutate']
|
let mutate: ApolloServerTestClient['mutate']
|
||||||
let con: DataSource
|
let con: DataSource
|
||||||
|
|||||||
@ -18,7 +18,6 @@ export const userFactory = async (
|
|||||||
// console.log('call createUser with', JSON.stringify(user, null, 2))
|
// console.log('call createUser with', JSON.stringify(user, null, 2))
|
||||||
const response = await mutate({ mutation: createUser, variables: user })
|
const response = await mutate({ mutation: createUser, variables: user })
|
||||||
if (!response?.data?.createUser) {
|
if (!response?.data?.createUser) {
|
||||||
// biome-ignore lint/suspicious/noConsole: will be used in tests where logging is mocked
|
|
||||||
// console.log(JSON.stringify(response, null, 2))
|
// console.log(JSON.stringify(response, null, 2))
|
||||||
throw new Error('createUser mutation returned unexpected response')
|
throw new Error('createUser mutation returned unexpected response')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { entities } from 'database'
|
|||||||
import { datatype, internet, name } from 'faker'
|
import { datatype, internet, name } from 'faker'
|
||||||
|
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { createServer } from '@/server/createServer'
|
import { createServer } from '@/server/createServer'
|
||||||
|
|
||||||
import { initLogging } from '@/server/logger'
|
import { initLogging } from '@/server/logger'
|
||||||
@ -17,7 +18,7 @@ import { userFactory } from './factory/user'
|
|||||||
import { transactionLinks } from './transactionLink/index'
|
import { transactionLinks } from './transactionLink/index'
|
||||||
import { users } from './users/index'
|
import { users } from './users/index'
|
||||||
|
|
||||||
CONFIG.EMAIL = false
|
CORE_CONFIG.EMAIL = false
|
||||||
const logger = getLogger('seed')
|
const logger = getLogger('seed')
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { schema } from '@/graphql/schema'
|
import { schema } from '@/graphql/schema'
|
||||||
import { elopageWebhook } from '@/webhook/elopage'
|
import { elopageWebhook } from '@/webhook/elopage'
|
||||||
import { gmsWebhook } from '@/webhook/gms'
|
import { gmsWebhook } from '@/webhook/gms'
|
||||||
@ -28,7 +29,6 @@ interface ServerDef {
|
|||||||
export const createServer = async (
|
export const createServer = async (
|
||||||
apolloLogger: Logger,
|
apolloLogger: Logger,
|
||||||
context: any = serverContext,
|
context: any = serverContext,
|
||||||
localization: i18n.I18n = i18n,
|
|
||||||
): Promise<ServerDef> => {
|
): Promise<ServerDef> => {
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.createServer`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.server.createServer`)
|
||||||
logger.debug('createServer...')
|
logger.debug('createServer...')
|
||||||
@ -75,7 +75,7 @@ export const createServer = async (
|
|||||||
app.use(urlencoded({ extended: true }))
|
app.use(urlencoded({ extended: true }))
|
||||||
|
|
||||||
// i18n
|
// i18n
|
||||||
app.use(localization.init)
|
app.use(i18n.init)
|
||||||
|
|
||||||
// Elopage Webhook
|
// Elopage Webhook
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ export const createServer = async (
|
|||||||
})
|
})
|
||||||
apollo.applyMiddleware({ app, path: '/' })
|
apollo.applyMiddleware({ app, path: '/' })
|
||||||
logger.info(
|
logger.info(
|
||||||
`running with PRODUCTION=${CONFIG.PRODUCTION}, sending EMAIL enabled=${CONFIG.EMAIL} and EMAIL_TEST_MODUS=${CONFIG.EMAIL_TEST_MODUS} ...`,
|
`running with PRODUCTION=${CONFIG.PRODUCTION}, sending EMAIL enabled=${CORE_CONFIG.EMAIL} and EMAIL_TEST_MODUS=${CORE_CONFIG.EMAIL_TEST_MODUS} ...`,
|
||||||
)
|
)
|
||||||
logger.debug('createServer...successful')
|
logger.debug('createServer...successful')
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import path from 'node:path'
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
||||||
import i18n from 'i18n'
|
import i18n from 'i18n'
|
||||||
import { getLogger } from 'log4js'
|
import { getLogger } from 'log4js'
|
||||||
@ -9,7 +8,10 @@ i18n.configure({
|
|||||||
locales: ['en', 'de'],
|
locales: ['en', 'de'],
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
retryInDefaultLocale: false,
|
retryInDefaultLocale: false,
|
||||||
directory: path.join(__dirname, '..', 'locales'),
|
staticCatalog: {
|
||||||
|
en: { general: { decimalSeparator: "." } },
|
||||||
|
de: { general: { decimalSeparator: "," } },
|
||||||
|
},
|
||||||
// autoReload: true, // if this is activated the seeding hangs at the very end
|
// autoReload: true, // if this is activated the seeding hangs at the very end
|
||||||
updateFiles: false,
|
updateFiles: false,
|
||||||
objectNotation: true,
|
objectNotation: true,
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import { entities } from 'database'
|
|||||||
|
|
||||||
import { createServer } from '@/server/createServer'
|
import { createServer } from '@/server/createServer'
|
||||||
|
|
||||||
import { i18n } from './testSetup'
|
|
||||||
|
|
||||||
import { getLogger } from 'log4js'
|
import { getLogger } from 'log4js'
|
||||||
|
|
||||||
export const headerPushMock = jest.fn((t) => {
|
export const headerPushMock = jest.fn((t) => {
|
||||||
@ -29,8 +27,8 @@ export const cleanDB = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const testEnvironment = async (testLogger = getLogger('apollo'), testI18n = i18n) => {
|
export const testEnvironment = async (testLogger = getLogger('apollo')) => {
|
||||||
const server = await createServer( testLogger, context, testI18n)
|
const server = await createServer( testLogger, context)
|
||||||
const con = server.con
|
const con = server.con
|
||||||
const testClient = createTestClient(server.apollo)
|
const testClient = createTestClient(server.apollo)
|
||||||
const mutate = testClient.mutate
|
const mutate = testClient.mutate
|
||||||
|
|||||||
@ -1,27 +1,13 @@
|
|||||||
import 'openai/shims/node'
|
import 'openai/shims/node'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import { i18n } from '@/server/localization'
|
import { CONFIG as CORE_CONFIG } from 'core'
|
||||||
import { getLogger, printLogs, clearLogs } from 'config-schema/test/testSetup'
|
import { getLogger, printLogs, clearLogs } from 'config-schema/test/testSetup'
|
||||||
|
|
||||||
CONFIG.EMAIL = true
|
CORE_CONFIG.EMAIL = false
|
||||||
CONFIG.EMAIL_TEST_MODUS = false
|
CORE_CONFIG.EMAIL_TEST_MODUS = false
|
||||||
CONFIG.HUMHUB_ACTIVE = false
|
CONFIG.HUMHUB_ACTIVE = false
|
||||||
CONFIG.GMS_ACTIVE = false
|
CONFIG.GMS_ACTIVE = false
|
||||||
|
|
||||||
jest.setTimeout(1000000)
|
jest.setTimeout(1000000)
|
||||||
|
|
||||||
jest.mock('@/server/localization', () => {
|
export { getLogger, printLogs, clearLogs as cleanLogs }
|
||||||
const originalModule = jest.requireActual<typeof i18n>('@/server/localization')
|
|
||||||
return {
|
|
||||||
__esModule: true,
|
|
||||||
...originalModule,
|
|
||||||
i18n: {
|
|
||||||
init: jest.fn(),
|
|
||||||
// configure: jest.fn(),
|
|
||||||
// __: jest.fn(),
|
|
||||||
// setLocale: jest.fn(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export { i18n, getLogger, printLogs, clearLogs as cleanLogs }
|
|
||||||
|
|||||||
@ -63,7 +63,7 @@
|
|||||||
"typeRoots": [ /* List of folders to include type definitions from. */
|
"typeRoots": [ /* List of folders to include type definitions from. */
|
||||||
"@types",
|
"@types",
|
||||||
"node_modules/@types",
|
"node_modules/@types",
|
||||||
"../node_modules/@types"
|
"../node_modules/@types",
|
||||||
],
|
],
|
||||||
// "types": [], /* Type declaration files to be included in compilation. */
|
// "types": [], /* Type declaration files to be included in compilation. */
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||||
@ -86,6 +86,9 @@
|
|||||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||||
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
|
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
|
||||||
},
|
},
|
||||||
|
"include": [
|
||||||
|
"../core/src/types"
|
||||||
|
],
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"swc": true
|
"swc": true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,10 +8,8 @@
|
|||||||
"locales": {},
|
"locales": {},
|
||||||
"locales:fix": {},
|
"locales:fix": {},
|
||||||
"lint": {
|
"lint": {
|
||||||
"dependsOn": ["locales"]
|
|
||||||
},
|
},
|
||||||
"lint:fix": {
|
"lint:fix": {
|
||||||
"dependsOn": ["locales:fix"]
|
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"dependsOn": ["database#up:backend_test", "^build"]
|
"dependsOn": ["database#up:backend_test", "^build"]
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "config-schema",
|
"name": "config-schema",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"description": "Gradido Config for validate config",
|
"description": "Gradido Config for validate config",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
"types": "./src/index.ts",
|
"types": "./src/index.ts",
|
||||||
|
|||||||
@ -35,6 +35,11 @@ export const COMMUNITY_URL = Joi.string()
|
|||||||
.default('http://0.0.0.0')
|
.default('http://0.0.0.0')
|
||||||
.required()
|
.required()
|
||||||
|
|
||||||
|
export const DLT_ACTIVE = Joi.boolean()
|
||||||
|
.description('Flag to indicate if the DLT (Decentralized Ledger Technology) service is used.')
|
||||||
|
.default(false)
|
||||||
|
.required()
|
||||||
|
|
||||||
export const GRAPHQL_URI = Joi.string()
|
export const GRAPHQL_URI = Joi.string()
|
||||||
.uri({ scheme: ['http', 'https'] })
|
.uri({ scheme: ['http', 'https'] })
|
||||||
.description(
|
.description(
|
||||||
|
|||||||
@ -17,17 +17,23 @@ export function validate(schema: ObjectSchema, data: any) {
|
|||||||
throw new Error('missing key in config validation with joi: ' + details)
|
throw new Error('missing key in config validation with joi: ' + details)
|
||||||
}
|
}
|
||||||
const value = err.context.value
|
const value = err.context.value
|
||||||
const description = schemaJson.keys[key]
|
try {
|
||||||
? schema.describe().keys[key].flags.description
|
const description = schemaJson.keys[key]
|
||||||
: 'No description available'
|
? schema.describe().keys[key].flags.description
|
||||||
if (data[key] === undefined) {
|
: 'No description available'
|
||||||
throw new Error(
|
if (data[key] === undefined) {
|
||||||
`Environment Variable '${key}' is missing. ${description}, details: ${details}`,
|
throw new Error(
|
||||||
)
|
`Environment Variable '${key}' is missing. ${description}, details: ${details}`,
|
||||||
} else {
|
)
|
||||||
throw new Error(
|
} else {
|
||||||
`Error on Environment Variable ${key} with value = ${value}: ${err.message}. ${description}`,
|
throw new Error(
|
||||||
)
|
`Error on Environment Variable ${key} with value = ${value}: ${err.message}. ${description}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// biome-ignore lint/suspicious/noConsole: schema validation may be run before logger is initialized
|
||||||
|
console.error('Error getting description for key ' + key + ': ' + e)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,8 @@ const getLoggerMocked = mock().mockImplementation((param: any) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mock.module('log4js', () => ({
|
mock.module('log4js', () => ({
|
||||||
getLogger: getLoggerMocked
|
getLogger: getLoggerMocked,
|
||||||
|
addLayout: jest.fn()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export function getLogger(name: string) {
|
export function getLogger(name: string) {
|
||||||
|
|||||||
16
core/esbuild.config.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { build } from 'esbuild'
|
||||||
|
|
||||||
|
build({
|
||||||
|
entryPoints: ['src/index.ts'],
|
||||||
|
outdir: 'build',
|
||||||
|
platform: 'node',
|
||||||
|
target: 'node18.20.7',
|
||||||
|
loader: {
|
||||||
|
'.png': 'binary',
|
||||||
|
'.jpeg': 'binary',
|
||||||
|
'.jpg': 'binary',
|
||||||
|
},
|
||||||
|
bundle: true,
|
||||||
|
sourcemap: true,
|
||||||
|
packages: 'external',
|
||||||
|
})
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "core",
|
"name": "core",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"description": "Gradido Core Code, High-Level Shared Code, with dependencies on other modules",
|
"description": "Gradido Core Code, High-Level Shared Code, with dependencies on other modules",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
"types": "./src/index.ts",
|
"types": "./src/index.ts",
|
||||||
@ -15,37 +15,46 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild src/index.ts --outdir=build --platform=node --target=node18.20.7 --bundle --packages=external",
|
"build": "bun esbuild.config.ts && mkdirp build/templates/ && ncp src/emails/templates build/templates",
|
||||||
"build:bun": "bun build src/index.ts --outdir=build --target=bun --packages=external",
|
"build:bun": "bun build src/index.ts --outdir=build --target=bun --packages=external",
|
||||||
"test": "bun test",
|
"test": "bun test",
|
||||||
"test:debug": "bun test --inspect-brk",
|
"test:debug": "bun test --inspect-brk",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "biome check --error-on-warnings .",
|
"lint": "biome check --error-on-warnings .",
|
||||||
"lint:fix": "biome check --error-on-warnings . --write",
|
"lint:fix": "biome check --error-on-warnings . --write",
|
||||||
|
"locales": "scripts/sort.sh src/emails/locales",
|
||||||
|
"locales:fix": "scripts/sort.sh src/emails/locales --fix",
|
||||||
"clear": "rm -rf node_modules && rm -rf build && rm -rf .turbo"
|
"clear": "rm -rf node_modules && rm -rf build && rm -rf .turbo"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"database": "*",
|
"database": "*",
|
||||||
|
"email-templates": "^10.0.1",
|
||||||
"esbuild": "^0.25.2",
|
"esbuild": "^0.25.2",
|
||||||
"i18n": "^0.15.1",
|
"i18n": "^0.15.1",
|
||||||
"joi": "^17.13.3",
|
"joi": "^17.13.3",
|
||||||
"jose": "^4.14.4",
|
"jose": "^4.14.4",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
|
"nodemailer": "^6.6.5",
|
||||||
|
"pug": "^3.0.2",
|
||||||
"shared": "*",
|
"shared": "*",
|
||||||
"sodium-native": "^3.4.1",
|
"sodium-native": "^3.4.1",
|
||||||
"zod": "^3.25.61"
|
"zod": "^3.25.61"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.0.0",
|
"@biomejs/biome": "2.0.0",
|
||||||
|
"@types/email-templates": "^10.0.4",
|
||||||
"@types/i18n": "^0.13.4",
|
"@types/i18n": "^0.13.4",
|
||||||
"@types/minimatch": "6.0.0",
|
"@types/minimatch": "6.0.0",
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "^17.0.21",
|
||||||
|
"@types/nodemailer": "^6.4.4",
|
||||||
"@types/sodium-native": "^2.3.5",
|
"@types/sodium-native": "^2.3.5",
|
||||||
"config-schema": "*",
|
"config-schema": "*",
|
||||||
"decimal.js-light": "^2.5.1",
|
"decimal.js-light": "^2.5.1",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
"graphql-request": "5.0.0",
|
"graphql-request": "5.0.0",
|
||||||
"jest": "27.2.4",
|
"jest": "27.2.4",
|
||||||
|
"mkdirp": "^3.0.1",
|
||||||
|
"ncp": "^2.0.0",
|
||||||
"type-graphql": "^1.1.1",
|
"type-graphql": "^1.1.1",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,11 +4,11 @@ ROOT_DIR=$(dirname "$0")/..
|
|||||||
|
|
||||||
exit_code=0
|
exit_code=0
|
||||||
|
|
||||||
for locale_file in $ROOT_DIR/src/locales/*.json
|
for locale_file in $ROOT_DIR/"$1"/*.json
|
||||||
do
|
do
|
||||||
jq -M 'to_entries | sort_by(.key) | from_entries' "$locale_file" > tmp.json
|
jq -M 'to_entries | sort_by(.key) | from_entries' "$locale_file" > tmp.json
|
||||||
|
|
||||||
if [ "$*" == "--fix" ]
|
if [ "$2" == "--fix" ]
|
||||||
then
|
then
|
||||||
mv tmp.json "$locale_file"
|
mv tmp.json "$locale_file"
|
||||||
else
|
else
|
||||||
@ -20,8 +20,34 @@ const federation = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const COMMUNITY_HOST = process.env.COMMUNITY_HOST ?? 'localhost'
|
||||||
|
const URL_PROTOCOL = process.env.URL_PROTOCOL ?? 'http'
|
||||||
|
const COMMUNITY_URL = process.env.COMMUNITY_URL ?? `${URL_PROTOCOL}://${COMMUNITY_HOST}`
|
||||||
|
|
||||||
|
const community = {
|
||||||
|
COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL ?? 'support@supportmail.com',
|
||||||
|
COMMUNITY_URL,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const email = {
|
||||||
|
EMAIL: process.env.EMAIL === 'true',
|
||||||
|
EMAIL_LINK_FORGOTPASSWORD:
|
||||||
|
COMMUNITY_URL + (process.env.EMAIL_LINK_FORGOTPASSWORD_PATH ?? '/forgot-password'),
|
||||||
|
EMAIL_TLS: process.env.EMAIL_TLS !== 'false',
|
||||||
|
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true',
|
||||||
|
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER ?? 'stage1@gradido.net',
|
||||||
|
EMAIL_USERNAME: process.env.EMAIL_USERNAME ?? '',
|
||||||
|
EMAIL_SENDER: process.env.EMAIL_SENDER ?? 'info@gradido.net',
|
||||||
|
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD ?? '',
|
||||||
|
EMAIL_SMTP_HOST: process.env.EMAIL_SMTP_HOST ?? 'mailserver',
|
||||||
|
EMAIL_SMTP_PORT: Number(process.env.EMAIL_SMTP_PORT) || 1025,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const CONFIG = {
|
export const CONFIG = {
|
||||||
...federation,
|
...federation,
|
||||||
|
...community,
|
||||||
|
...email,
|
||||||
}
|
}
|
||||||
validate(schema, CONFIG)
|
validate(schema, CONFIG)
|
||||||
|
|||||||
@ -1,6 +1,93 @@
|
|||||||
|
|
||||||
import Joi from 'joi'
|
import Joi from 'joi'
|
||||||
|
import { COMMUNITY_SUPPORT_MAIL, COMMUNITY_URL, NODE_ENV } from 'config-schema'
|
||||||
|
|
||||||
export const schema = Joi.object({
|
export const schema = Joi.object({
|
||||||
|
COMMUNITY_SUPPORT_MAIL,
|
||||||
|
COMMUNITY_URL,
|
||||||
|
NODE_ENV,
|
||||||
|
|
||||||
|
EMAIL: Joi.boolean()
|
||||||
|
.default(false)
|
||||||
|
.description('Enable or disable email functionality')
|
||||||
|
.required(),
|
||||||
|
|
||||||
|
EMAIL_LINK_FORGOTPASSWORD: Joi.string()
|
||||||
|
.uri({ scheme: ['http', 'https'] })
|
||||||
|
.custom((value: string, helpers: Joi.CustomHelpers<string>): string | Joi.ErrorReport => {
|
||||||
|
if (!value.startsWith(helpers.state.ancestors[0].COMMUNITY_URL)) {
|
||||||
|
return helpers.error('string.pattern.base', { value, communityUrl: COMMUNITY_URL })
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
.description('Email Verification link for set new Password, when old Password was forgotten.')
|
||||||
|
.required(),
|
||||||
|
|
||||||
|
EMAIL_TEST_MODUS: Joi.boolean()
|
||||||
|
.default(false)
|
||||||
|
.description('When enabled, all emails are sended to EMAIL_TEST_RECEIVER')
|
||||||
|
.optional(),
|
||||||
|
|
||||||
|
EMAIL_TEST_RECEIVER: Joi.string()
|
||||||
|
.email()
|
||||||
|
.default('stage1@gradido.net')
|
||||||
|
.when('EMAIL_TEST_MODUS', { is: true, then: Joi.required() })
|
||||||
|
.description('Email address used in test mode'),
|
||||||
|
|
||||||
|
EMAIL_USERNAME: Joi.alternatives().conditional(Joi.ref('EMAIL'), {
|
||||||
|
is: true,
|
||||||
|
then: Joi.alternatives().conditional(Joi.ref('NODE_ENV'), {
|
||||||
|
is: 'development',
|
||||||
|
then: Joi.string()
|
||||||
|
.allow('')
|
||||||
|
.description('Username for SMTP authentication (optional in development)'),
|
||||||
|
otherwise: Joi.string()
|
||||||
|
.pattern(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)
|
||||||
|
.description('Valid SMTP username required in production')
|
||||||
|
.required(),
|
||||||
|
}),
|
||||||
|
otherwise: Joi.string().allow('').optional(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
EMAIL_SENDER: Joi.string()
|
||||||
|
.email()
|
||||||
|
.when('EMAIL', { is: true, then: Joi.required() })
|
||||||
|
.default('info@gradido.net')
|
||||||
|
.description('Email address used as sender'),
|
||||||
|
|
||||||
|
EMAIL_PASSWORD: Joi.alternatives().conditional(Joi.ref('EMAIL'), {
|
||||||
|
is: true,
|
||||||
|
then: Joi.alternatives().conditional(Joi.ref('NODE_ENV'), {
|
||||||
|
is: 'development',
|
||||||
|
then: Joi.string()
|
||||||
|
.allow('')
|
||||||
|
.description('Password for SMTP authentication (optional in development)'),
|
||||||
|
otherwise: Joi.string()
|
||||||
|
.min(8)
|
||||||
|
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&#]).{8,}$/)
|
||||||
|
.description(
|
||||||
|
'Password must be at least 8 characters long, include uppercase and lowercase letters, a number, and a special character',
|
||||||
|
)
|
||||||
|
.required(),
|
||||||
|
}),
|
||||||
|
otherwise: Joi.string().allow('').optional(),
|
||||||
|
}),
|
||||||
|
|
||||||
|
EMAIL_SMTP_HOST: Joi.string()
|
||||||
|
.hostname()
|
||||||
|
.when('EMAIL', { is: true, then: Joi.required() })
|
||||||
|
.default('mailserver')
|
||||||
|
.description('SMTP server hostname'),
|
||||||
|
|
||||||
|
EMAIL_SMTP_PORT: Joi.number()
|
||||||
|
.integer()
|
||||||
|
.positive()
|
||||||
|
.when('EMAIL', { is: true, then: Joi.required() })
|
||||||
|
.default(1025)
|
||||||
|
.description('SMTP server port'),
|
||||||
|
|
||||||
|
EMAIL_TLS: Joi.boolean().default(true).description('Enable or disable TLS for SMTP').optional(),
|
||||||
|
|
||||||
FEDERATION_BACKEND_SEND_ON_API: Joi.string()
|
FEDERATION_BACKEND_SEND_ON_API: Joi.string()
|
||||||
.pattern(/^\d+_\d+$/)
|
.pattern(/^\d+_\d+$/)
|
||||||
.default('1_0')
|
.default('1_0')
|
||||||
|
|||||||
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendAccountActivationEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendAccountActivationEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -133,41 +133,41 @@ exports[`sendEmailVariants sendAccountActivationEmail result has the correct htm
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Email Verification</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Email Verification</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Your email address has just been registered with Gradido.</p>
|
<p>Your email address has just been registered with Gradido.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Complete registration</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Complete registration</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please click here to complete the registration and activate your Gradido account.</div><a class=\\"button-3\\" href=\\"http://localhost/checkEmail/6627633878930542284\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">Activate account</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please click here to complete the registration and activate your Gradido account.</div><a class=\"button-3\" href=\"http://localhost/checkEmail/6627633878930542284\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">Activate account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"http://localhost/checkEmail/6627633878930542284\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">http://localhost/checkEmail/6627633878930542284</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"http://localhost/checkEmail/6627633878930542284\" style=\"line-break: anywhere; margin-bottom: 40px;\">http://localhost/checkEmail/6627633878930542284</a>
|
||||||
<requestnewlink>
|
<requestnewlink>
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Request new valid link</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Request new valid link</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">The link has a validity of 23 hours and 30 minutes.
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">The link has a validity of 23 hours and 30 minutes.
|
||||||
If the validity of the link has already expired, you can have a new link sent to you here.</div><a class=\\"button-4\\" href=\\"http://localhost/forgot-password\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%; background-image: radial-gradient(circle farthest-corner at 0% 0%, #616161, #c2c2c2);\\">New link</a>
|
If the validity of the link has already expired, you can have a new link sent to you here.</div><a class=\"button-4\" href=\"http://localhost/forgot-password\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%; background-image: radial-gradient(circle farthest-corner at 0% 0%, #616161, #c2c2c2);\">New link</a>
|
||||||
</requestnewlink>
|
</requestnewlink>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -178,12 +178,12 @@ If the validity of the link has already expired, you can have a new link sent to
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendAccountMultiRegistrationEmail calls "sendEmailTranslated" result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendAccountMultiRegistrationEmail calls "sendEmailTranslated" result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -309,39 +309,39 @@ exports[`sendEmailVariants sendAccountMultiRegistrationEmail calls "sendEmailTra
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Try To Register Again With Your Email</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Try To Register Again With Your Email</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Your email address has just been used again to register an account with Gradido.<br>However, an account already exists for your email address.
|
<p>Your email address has just been used again to register an account with Gradido.<br>However, an account already exists for your email address.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Reset password</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Reset password</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">If you have forgotten your password, please click here.</div><a class=\\"button-3\\" href=\\"http://localhost/forgot-password\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">reset</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">If you have forgotten your password, please click here.</div><a class=\"button-3\" href=\"http://localhost/forgot-password\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">reset</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"http://localhost/forgot-password\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">http://localhost/forgot-password</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"http://localhost/forgot-password\" style=\"line-break: anywhere; margin-bottom: 40px;\">http://localhost/forgot-password</a>
|
||||||
<h2 style=\\"margin-top: 15px; color: red;\\">Contact support</h2>
|
<h2 style=\"margin-top: 15px; color: red;\">Contact support</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">If you did not try to register again, please contact our support:</div><a class=\\"clink\\" href=\\"mailto:support@supportmail.com\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">support@supportmail.com</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">If you did not try to register again, please contact our support:</div><a class=\"clink\" href=\"mailto:support@supportmail.com\" style=\"line-break: anywhere; margin-bottom: 40px;\">support@supportmail.com</a>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -352,12 +352,12 @@ exports[`sendEmailVariants sendAccountMultiRegistrationEmail calls "sendEmailTra
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendAddedContributionMessageEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendAddedContributionMessageEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -483,39 +483,39 @@ exports[`sendEmailVariants sendAddedContributionMessageEmail result has the corr
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Message about your common good contribution</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Message about your common good contribution</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>You have received a message from Bibi Bloxberg regarding your common good contribution “My contribution.”.</p>
|
<p>You have received a message from Bibi Bloxberg regarding your common good contribution “My contribution.”.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Read and reply to message</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Read and reply to message</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">
|
||||||
<p>„My message.“</p>
|
<p>„My message.“</p>
|
||||||
<p>To reply to the message, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</p>
|
<p>To reply to the message, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</p>
|
||||||
</div><a class=\\"button-3\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
</div><a class=\"button-3\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -526,12 +526,12 @@ exports[`sendEmailVariants sendAddedContributionMessageEmail result has the corr
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendContributionChangedByModeratorEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendContributionChangedByModeratorEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -657,37 +657,37 @@ exports[`sendEmailVariants sendContributionChangedByModeratorEmail result has th
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Your common good contribution has been changed</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Your common good contribution has been changed</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>your common good contribution 'My contribution.' has just been changed by Bibi Bloxberg and now reads as 'This is a better contribution memo.'</p>
|
<p>your common good contribution 'My contribution.' has just been changed by Bibi Bloxberg and now reads as 'This is a better contribution memo.'</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Contribution details</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Contribution details</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\\"button-3\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\"button-3\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"line-break: anywhere; margin-bottom: 40px;\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -698,12 +698,12 @@ exports[`sendEmailVariants sendContributionChangedByModeratorEmail result has th
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendContributionConfirmedEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendContributionConfirmedEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -829,37 +829,37 @@ exports[`sendEmailVariants sendContributionConfirmedEmail result has the correct
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Your contribution to the common good was confirmed</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Your contribution to the common good was confirmed</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Your common good contribution “My contribution.” has just been approved by Bibi Bloxberg. Your Gradido account has been credited with 23.54 GDD.</p>
|
<p>Your common good contribution “My contribution.” has just been approved by Bibi Bloxberg. Your Gradido account has been credited with 23.54 GDD.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Contribution details</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Contribution details</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\\"button-3\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\"button-3\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"line-break: anywhere; margin-bottom: 40px;\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -870,12 +870,12 @@ exports[`sendEmailVariants sendContributionConfirmedEmail result has the correct
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendContributionDeletedEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendContributionDeletedEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1001,37 +1001,37 @@ exports[`sendEmailVariants sendContributionDeletedEmail result has the correct h
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Your common good contribution was deleted</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Your common good contribution was deleted</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Your common good contribution “My contribution.” was deleted by Bibi Bloxberg.</p>
|
<p>Your common good contribution “My contribution.” was deleted by Bibi Bloxberg.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Contribution details</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Contribution details</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\\"button-3\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\"button-3\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"line-break: anywhere; margin-bottom: 40px;\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1042,12 +1042,12 @@ exports[`sendEmailVariants sendContributionDeletedEmail result has the correct h
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendContributionDeniedEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendContributionDeniedEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1173,37 +1173,37 @@ exports[`sendEmailVariants sendContributionDeniedEmail result has the correct ht
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Your common good contribution was rejected</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Your common good contribution was rejected</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Your common good contribution “My contribution.” was rejected by Bibi Bloxberg.</p>
|
<p>Your common good contribution “My contribution.” was rejected by Bibi Bloxberg.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Contribution details</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Contribution details</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\\"button-3\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">To see your common good contributions and related messages, go to the “Creation” menu in your Gradido account and click on the “My contributions” tab.</div><a class=\"button-3\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"https://gradido.net/contributions/own-contributions/1#contributionListItem-1\" style=\"line-break: anywhere; margin-bottom: 40px;\">https://gradido.net/contributions/own-contributions/1#contributionListItem-1</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1214,12 +1214,12 @@ exports[`sendEmailVariants sendContributionDeniedEmail result has the correct ht
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendResetPasswordEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendResetPasswordEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1345,41 +1345,41 @@ exports[`sendEmailVariants sendResetPasswordEmail result has the correct html as
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Reset password</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Reset password</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>You, or someone else, requested a password reset for this account.</p>
|
<p>You, or someone else, requested a password reset for this account.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Reset password</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Reset password</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">If it was you, please click here.</div><a class=\\"button-3\\" href=\\"http://localhost/reset-password/3762660021544901417\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">reset</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">If it was you, please click here.</div><a class=\"button-3\" href=\"http://localhost/reset-password/3762660021544901417\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">reset</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Or copy the link into your browser window.</div><a class=\\"clink\\" href=\\"http://localhost/reset-password/3762660021544901417\\" style=\\"line-break: anywhere; margin-bottom: 40px;\\">http://localhost/reset-password/3762660021544901417</a>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Or copy the link into your browser window.</div><a class=\"clink\" href=\"http://localhost/reset-password/3762660021544901417\" style=\"line-break: anywhere; margin-bottom: 40px;\">http://localhost/reset-password/3762660021544901417</a>
|
||||||
<requestnewlink>
|
<requestnewlink>
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Request new valid link</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Request new valid link</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">The link has a validity of 23 hours and 30 minutes.
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">The link has a validity of 23 hours and 30 minutes.
|
||||||
If the validity of the link has already expired, you can have a new link sent to you here.</div><a class=\\"button-4\\" href=\\"http://localhost/forgot-password\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%; background-image: radial-gradient(circle farthest-corner at 0% 0%, #616161, #c2c2c2);\\">New link</a>
|
If the validity of the link has already expired, you can have a new link sent to you here.</div><a class=\"button-4\" href=\"http://localhost/forgot-password\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%; background-image: radial-gradient(circle farthest-corner at 0% 0%, #616161, #c2c2c2);\">New link</a>
|
||||||
</requestnewlink>
|
</requestnewlink>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1390,12 +1390,12 @@ If the validity of the link has already expired, you can have a new link sent to
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendTransactionLinkRedeemedEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendTransactionLinkRedeemedEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1521,37 +1521,37 @@ exports[`sendEmailVariants sendTransactionLinkRedeemedEmail result has the corre
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Bibi Bloxberg has redeemed your Gradido link</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Bibi Bloxberg has redeemed your Gradido link</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p>Bibi Bloxberg (bibi@bloxberg.de) has just redeemed your link.</p>
|
<p>Bibi Bloxberg (bibi@bloxberg.de) has just redeemed your link.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Transaction details</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Transaction details</h2>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Amount: 17.65 GDD<br>Message: You deserve it! 🙏🏼<br>You can find transaction details in your Gradido account.
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Amount: 17.65 GDD<br>Message: You deserve it! 🙏🏼<br>You can find transaction details in your Gradido account.
|
||||||
</div><a class=\\"button-3\\" href=\\"http://localhost/transactions\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
</div><a class=\"button-3\" href=\"http://localhost/transactions\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Please do not reply to this email.</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Please do not reply to this email.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1562,12 +1562,12 @@ exports[`sendEmailVariants sendTransactionLinkRedeemedEmail result has the corre
|
|||||||
|
|
||||||
exports[`sendEmailVariants sendTransactionReceivedEmail result has the correct html as snapshot 1`] = `
|
exports[`sendEmailVariants sendTransactionReceivedEmail result has the correct html as snapshot 1`] = `
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html lang=\\"en\\">
|
<html lang=\"en\">
|
||||||
<head>
|
<head>
|
||||||
<meta content=\\"multipart/html; charset=UTF-8\\" http-equiv=\\"content-type\\">
|
<meta content=\"multipart/html; charset=UTF-8\" http-equiv=\"content-type\">
|
||||||
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\">
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
||||||
<style>
|
<style>
|
||||||
.wf-force-outline-none[tabindex=\\"-1\\"]:focus {
|
.wf-force-outline-none[tabindex=\"-1\"]:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -1693,40 +1693,40 @@ exports[`sendEmailVariants sendTransactionReceivedEmail result has the correct h
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style=\\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\\">
|
<body style=\"display: block; font-family: 'Work Sans', sans-serif; font-size: 17px; text-align: center; text-align: -webkit-center; justify-content: center; padding: 0px; margin: 0px;\">
|
||||||
<div class=\\"container\\" style=\\"max-width: 680px; margin: 0 auto; display: block;\\">
|
<div class=\"container\" style=\"max-width: 680px; margin: 0 auto; display: block;\">
|
||||||
<header>
|
<header>
|
||||||
<div class=\\"head\\"><img class=\\"head-logo\\" alt=\\"Gradido Logo\\" loading=\\"lazy\\" src=\\"cid:gradidoheader\\" style=\\"width: 100%; height: auto;\\"></div>
|
<div class=\"head\"><img class=\"head-logo\" alt=\"Gradido Logo\" loading=\"lazy\" src=\"cid:gradidoheader\" style=\"width: 100%; height: auto;\"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class=\\"wrapper\\">
|
<div class=\"wrapper\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Bibi Bloxberg has sent you 37.40 Gradido</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Bibi Bloxberg has sent you 37.40 Gradido</h2>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Hello Peter Lustig,</p>
|
<p>Hello Peter Lustig,</p>
|
||||||
<p> You have just received 37.40 GDD from Bibi Bloxberg (<a href=\\"mailto:bibi@bloxberg.de?subject=RE%3A%20Bibi%20Bloxberg%20has%20sent%20you%2037.40%20Gradido\\">bibi@bloxberg.de</a>).
|
<p> You have just received 37.40 GDD from Bibi Bloxberg (<a href=\"mailto:bibi@bloxberg.de?subject=RE%3A%20Bibi%20Bloxberg%20has%20sent%20you%2037.40%20Gradido\">bibi@bloxberg.de</a>).
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"content\\" style=\\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\\">
|
<div class=\"content\" style=\"display: block; width: 78%; margin: 40px 1% 40px 1%; padding: 20px 10% 40px 10%; border-radius: 24px; background-image: linear-gradient(180deg, #f5f5f5, #f5f5f5);\">
|
||||||
<h2 style=\\"margin-top: 15px; color: #383838;\\">Message</h2>
|
<h2 style=\"margin-top: 15px; color: #383838;\">Message</h2>
|
||||||
<div class=\\"child-left\\" style=\\"text-align: left;\\">
|
<div class=\"child-left\" style=\"text-align: left;\">
|
||||||
<div class=\\"p_content\\" style=\\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\\">Du bist schon lustiger ;)</div>
|
<div class=\"p_content\" style=\"margin: 15px 0 15px 0; line-height: 26px; color: #696c72;\">Du bist schon lustiger ;)</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=\\"child-right\\" style=\\"text-align: right;\\"><a class=\\"button-5\\" href=\\"mailto:bibi@bloxberg.de?subject=RE%3A%20Bibi%20Bloxberg%20has%20sent%20you%2037.40%20Gradido\\" style=\\"display: inline-block; padding: 9px 15px; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); margin: 25px 0 25px 0; background: linear-gradient(135deg, #53900c, #6e6e6e); font-size: 20px; font-weight: 600; color: #f5f5f5; width: auto; box-shadow: 20px 20px 25px; transition: all 0.3s ease;\\"><span class=\\"chatbox-wrapper\\" style=\\"margin-right: 8px;\\"><img class=\\"bi-chatbox\\" alt=\\"chatbox\\" loading=\\"lazy\\" src=\\"cid:chatboxicon\\" style=\\"margin-bottom: -5px;\\"></span><span>Reply</span></a>
|
<div class=\"child-right\" style=\"text-align: right;\"><a class=\"button-5\" href=\"mailto:bibi@bloxberg.de?subject=RE%3A%20Bibi%20Bloxberg%20has%20sent%20you%2037.40%20Gradido\" style=\"display: inline-block; padding: 9px 15px; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); margin: 25px 0 25px 0; background: linear-gradient(135deg, #53900c, #6e6e6e); font-size: 20px; font-weight: 600; color: #f5f5f5; width: auto; box-shadow: 20px 20px 25px; transition: all 0.3s ease;\"><span class=\"chatbox-wrapper\" style=\"margin-right: 8px;\"><img class=\"bi-chatbox\" alt=\"chatbox\" loading=\"lazy\" src=\"cid:chatboxicon\" style=\"margin-bottom: -5px;\"></span><span>Reply</span></a>
|
||||||
</div>
|
</div>
|
||||||
</div><a class=\\"button-3\\" href=\\"http://localhost/transactions\\" style=\\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\\">To account</a>
|
</div><a class=\"button-3\" href=\"http://localhost/transactions\" style=\"display: inline-block; padding: 9px 15px; color: white; border: 0; line-height: inherit; text-decoration: none; cursor: pointer; border-radius: 20px; background-image: radial-gradient(circle farthest-corner at 0% 0%, #f9cd69, #c58d38); box-shadow: 16px 13px 35px 0 rgba(56, 56, 56, 0.3); margin: 25px 0 25px 0; width: 50%;\">To account</a>
|
||||||
<div class=\\"text-block\\" style=\\"margin-top: 20px; color: #9ca0a8;\\">
|
<div class=\"text-block\" style=\"margin-top: 20px; color: #9ca0a8;\">
|
||||||
<p>Kind regards,<br>your Gradido team
|
<p>Kind regards,<br>your Gradido team
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class=\\"w-container footer_01\\">
|
<div class=\"w-container footer_01\">
|
||||||
<div class=\\"socialmedia\\" style=\\"display: flex; margin-top: 40px; max-width: 600px;\\"><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.facebook.com/groups/Gradido/\\" style=\\"width: 150px;\\"><img class=\\"bi-facebook\\" alt=\\"facebook\\" loading=\\"lazy\\" src=\\"cid:facebookicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://t.me/GradidoGruppe\\" style=\\"width: 150px;\\"><img class=\\"bi-telegram\\" alt=\\"Telegram\\" loading=\\"lazy\\" src=\\"cid:telegramicon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://twitter.com/gradido\\" style=\\"width: 150px;\\"><img class=\\"bi-twitter\\" alt=\\"Twitter\\" loading=\\"lazy\\" src=\\"cid:twittericon\\"></a><a class=\\"slink\\" target=\\"_blank\\" href=\\"https://www.youtube.com/c/GradidoNet\\" style=\\"width: 150px;\\"><img class=\\"bi-youtube\\" alt=\\"youtube\\" loading=\\"lazy\\" src=\\"cid:youtubeicon\\"></a></div>
|
<div class=\"socialmedia\" style=\"display: flex; margin-top: 40px; max-width: 600px;\"><a class=\"slink\" target=\"_blank\" href=\"https://www.facebook.com/groups/Gradido/\" style=\"width: 150px;\"><img class=\"bi-facebook\" alt=\"facebook\" loading=\"lazy\" src=\"cid:facebookicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://t.me/GradidoGruppe\" style=\"width: 150px;\"><img class=\"bi-telegram\" alt=\"Telegram\" loading=\"lazy\" src=\"cid:telegramicon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://twitter.com/gradido\" style=\"width: 150px;\"><img class=\"bi-twitter\" alt=\"Twitter\" loading=\"lazy\" src=\"cid:twittericon\"></a><a class=\"slink\" target=\"_blank\" href=\"https://www.youtube.com/c/GradidoNet\" style=\"width: 150px;\"><img class=\"bi-youtube\" alt=\"youtube\" loading=\"lazy\" src=\"cid:youtubeicon\"></a></div>
|
||||||
<div class=\\"line\\" style=\\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\\"></div>
|
<div class=\"line\" style=\"width: 100%; height: 13px; margin-top: 40px; background-image: linear-gradient(90deg, #c58d38, #f3cd7c 40%, #dbb056 55%, #eec05f 71%, #cc9d3d);\"></div>
|
||||||
<div class=\\"footer\\" style=\\"padding-bottom: 20px;\\">
|
<div class=\"footer\" style=\"padding-bottom: 20px;\">
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">If you have any further questions, please contact our support.</div><a class=\\"footer_p2\\" href=\\"mailto:support@gradido.net\\" style=\\"color: #383838; font-weight: bold;\\">support@gradido.net</a>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">If you have any further questions, please contact our support.</div><a class=\"footer_p2\" href=\"mailto:support@gradido.net\" style=\"color: #383838; font-weight: bold;\">support@gradido.net</a>
|
||||||
<div> <img class=\\"image\\" alt=\\"Gradido Logo\\" src=\\"https://gdd.gradido.net/img/brand/green.png\\" style=\\"width: 200px; margin-top: 30px; margin-bottom: 30px;\\" width=\\"200\\"></div>
|
<div> <img class=\"image\" alt=\"Gradido Logo\" src=\"https://gdd.gradido.net/img/brand/green.png\" style=\"width: 200px; margin-top: 30px; margin-bottom: 30px;\" width=\"200\"></div>
|
||||||
<div><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/impressum/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Impressum</a></div><br><a class=\\"terms_of_use\\" href=\\"https://gradido.net/de/datenschutz/\\" target=\\"_blank\\" style=\\"color: #9ca0a8;\\">Privacy Policy</a>
|
<div><a class=\"terms_of_use\" href=\"https://gradido.net/de/impressum/\" target=\"_blank\" style=\"color: #9ca0a8;\">Impressum</a></div><br><a class=\"terms_of_use\" href=\"https://gradido.net/de/datenschutz/\" target=\"_blank\" style=\"color: #9ca0a8;\">Privacy Policy</a>
|
||||||
<div class=\\"footer_p1\\" style=\\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
<div class=\"footer_p1\" style=\"margin-top: 30px; color: #9ca0a8; margin-bottom: 30px;\">Gradido-Akademie<br>Institut für Wirtschaftsbionik<br>Pfarrweg 2<br>74653 Künzelsau<br>Deutschland<br><br><br></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
1
core/src/emails/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './sendEmailVariants'
|
||||||
7
core/src/emails/localization.test.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { i18n } from './localization'
|
||||||
|
|
||||||
|
describe('localization', () => {
|
||||||
|
it('translate emails.accountMultiRegistration.contactSupport with Contact support', () => {
|
||||||
|
expect(i18n.__('emails.accountMultiRegistration.contactSupport')).toBe('Contact support')
|
||||||
|
})
|
||||||
|
})
|
||||||
31
core/src/emails/localization.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import en from './locales/en.json'
|
||||||
|
import de from './locales/de.json'
|
||||||
|
import { I18n } from 'i18n'
|
||||||
|
|
||||||
|
function flatten(obj: any, prefix: string = ''): any {
|
||||||
|
const result: any = {}
|
||||||
|
for (const key in obj) {
|
||||||
|
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
||||||
|
Object.assign(result, flatten(obj[key], prefix + key + '.'))
|
||||||
|
} else {
|
||||||
|
result[prefix + key] = obj[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export const i18n = new I18n({
|
||||||
|
locales: ['en', 'de'],
|
||||||
|
defaultLocale: 'en',
|
||||||
|
staticCatalog: { en: flatten(en), de: flatten(de) },
|
||||||
|
api: {
|
||||||
|
__: 't', // now req.__ becomes req.t
|
||||||
|
__n: 'tn', // and req.__n can be called as req.tn
|
||||||
|
},
|
||||||
|
register: global,
|
||||||
|
mustacheConfig: {
|
||||||
|
tags: ['{', '}'],
|
||||||
|
disable: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
@ -1,12 +1,10 @@
|
|||||||
import { createTransport } from 'nodemailer'
|
import { createTransport } from 'nodemailer'
|
||||||
|
import { CONFIG } from '../config'
|
||||||
import { i18n } from '@test/testSetup'
|
import { i18n } from './localization'
|
||||||
|
import { getLogger } from '../../../config-schema/test/testSetup.bun'
|
||||||
import { CONFIG } from '@/config'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const'
|
||||||
|
|
||||||
import { getLogger } from 'config-schema/test/testSetup'
|
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
|
||||||
import { sendEmailTranslated } from './sendEmailTranslated'
|
import { sendEmailTranslated } from './sendEmailTranslated'
|
||||||
|
import { mock, jest, describe, it, expect, beforeEach, afterAll } from 'bun:test'
|
||||||
|
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`)
|
||||||
|
|
||||||
@ -21,9 +19,8 @@ CONFIG.EMAIL_USERNAME = 'user'
|
|||||||
CONFIG.EMAIL_PASSWORD = 'pwd'
|
CONFIG.EMAIL_PASSWORD = 'pwd'
|
||||||
CONFIG.EMAIL_TLS = true
|
CONFIG.EMAIL_TLS = true
|
||||||
|
|
||||||
jest.mock('nodemailer', () => {
|
mock.module('nodemailer', () => {
|
||||||
return {
|
return {
|
||||||
__esModule: true,
|
|
||||||
createTransport: jest.fn(() => {
|
createTransport: jest.fn(() => {
|
||||||
return {
|
return {
|
||||||
sendMail: () => {
|
sendMail: () => {
|
||||||
@ -36,6 +33,13 @@ jest.mock('nodemailer', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.restoreAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
const spySetLocale = jest.spyOn(i18n, 'setLocale')
|
||||||
|
const spyTranslate = jest.spyOn(i18n, '__')
|
||||||
|
|
||||||
describe('sendEmailTranslated', () => {
|
describe('sendEmailTranslated', () => {
|
||||||
let result: Record<string, unknown> | boolean | null
|
let result: Record<string, unknown> | boolean | null
|
||||||
|
|
||||||
@ -48,7 +52,7 @@ describe('sendEmailTranslated', () => {
|
|||||||
},
|
},
|
||||||
template: 'accountMultiRegistration',
|
template: 'accountMultiRegistration',
|
||||||
locals: {
|
locals: {
|
||||||
locale: 'en',
|
language: 'en',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -72,7 +76,7 @@ describe('sendEmailTranslated', () => {
|
|||||||
},
|
},
|
||||||
template: 'accountMultiRegistration',
|
template: 'accountMultiRegistration',
|
||||||
locals: {
|
locals: {
|
||||||
locale: 'en',
|
language: 'en',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -106,12 +110,12 @@ describe('sendEmailTranslated', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('calls "i18n.setLocale" with "en"', () => {
|
it('calls "i18n.setLocale" with "en"', async () => {
|
||||||
expect(i18n.setLocale).toBeCalledWith('en')
|
expect(spySetLocale).toBeCalledWith('en')
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('calls "i18n.__" for translation', () => {
|
it('calls "i18n.__" for translation', () => {
|
||||||
expect(i18n.__).toBeCalled()
|
expect(spyTranslate).toBeCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -127,7 +131,7 @@ describe('sendEmailTranslated', () => {
|
|||||||
},
|
},
|
||||||
template: 'accountMultiRegistration',
|
template: 'accountMultiRegistration',
|
||||||
locals: {
|
locals: {
|
||||||
locale: 'en',
|
language: 'en',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1,12 +1,16 @@
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
import Email from 'email-templates'
|
import Email from 'email-templates'
|
||||||
import i18n from 'i18n'
|
import { i18n } from './localization'
|
||||||
import { createTransport } from 'nodemailer'
|
import { createTransport } from 'nodemailer'
|
||||||
|
import { CONFIG } from '../config'
|
||||||
import { CONFIG } from '@/config'
|
import { LOG4JS_BASE_CATEGORY_NAME } from '../config/const'
|
||||||
import { LOG4JS_BASE_CATEGORY_NAME } from '@/config/const'
|
|
||||||
import { getLogger } from 'log4js'
|
import { getLogger } from 'log4js'
|
||||||
|
import gradidoHeader from './templates/includes/gradido-header.jpeg'
|
||||||
|
import facebookIcon from './templates/includes/facebook-icon.png'
|
||||||
|
import telegramIcon from './templates/includes/telegram-icon.png'
|
||||||
|
import twitterIcon from './templates/includes/twitter-icon.png'
|
||||||
|
import youtubeIcon from './templates/includes/youtube-icon.png'
|
||||||
|
import chatboxIcon from './templates/includes/chatbox-icon.png'
|
||||||
|
|
||||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`)
|
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.emails.sendEmailTranslated`)
|
||||||
|
|
||||||
@ -21,7 +25,7 @@ export const sendEmailTranslated = async ({
|
|||||||
}
|
}
|
||||||
template: string
|
template: string
|
||||||
locals: Record<string, unknown>
|
locals: Record<string, unknown>
|
||||||
}): Promise<Record<string, unknown> | boolean | null> => {
|
}): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
// TODO: test the calling order of 'i18n.setLocale' for example: language of logging 'en', language of email receiver 'es', reset language of current user 'de'
|
// TODO: test the calling order of 'i18n.setLocale' for example: language of logging 'en', language of email receiver 'es', reset language of current user 'de'
|
||||||
|
|
||||||
if (!CONFIG.EMAIL) {
|
if (!CONFIG.EMAIL) {
|
||||||
@ -31,7 +35,6 @@ export const sendEmailTranslated = async ({
|
|||||||
|
|
||||||
// because language of receiver can differ from language of current user who triggers the sending
|
// because language of receiver can differ from language of current user who triggers the sending
|
||||||
// const rememberLocaleToRestore = i18n.getLocale()
|
// const rememberLocaleToRestore = i18n.getLocale()
|
||||||
|
|
||||||
i18n.setLocale('en') // for logging
|
i18n.setLocale('en') // for logging
|
||||||
logger.info(
|
logger.info(
|
||||||
`send Email: language=${locals.locale as string} to=${receiver.to.substring(0, 3)}...` +
|
`send Email: language=${locals.locale as string} to=${receiver.to.substring(0, 3)}...` +
|
||||||
@ -45,6 +48,7 @@ export const sendEmailTranslated = async ({
|
|||||||
)
|
)
|
||||||
receiver.to = CONFIG.EMAIL_TEST_RECEIVER
|
receiver.to = CONFIG.EMAIL_TEST_RECEIVER
|
||||||
}
|
}
|
||||||
|
|
||||||
const transport = createTransport({
|
const transport = createTransport({
|
||||||
host: CONFIG.EMAIL_SMTP_HOST,
|
host: CONFIG.EMAIL_SMTP_HOST,
|
||||||
port: CONFIG.EMAIL_SMTP_PORT,
|
port: CONFIG.EMAIL_SMTP_PORT,
|
||||||
@ -56,8 +60,7 @@ export const sendEmailTranslated = async ({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
i18n.setLocale(locals.locale as string) // for email
|
i18n.setLocale(locals.language as string) // for email
|
||||||
|
|
||||||
// TESTING: see 'README.md'
|
// TESTING: see 'README.md'
|
||||||
const email = new Email({
|
const email = new Email({
|
||||||
message: {
|
message: {
|
||||||
@ -66,9 +69,7 @@ export const sendEmailTranslated = async ({
|
|||||||
send: CONFIG.EMAIL,
|
send: CONFIG.EMAIL,
|
||||||
transport,
|
transport,
|
||||||
preview: false,
|
preview: false,
|
||||||
// i18n, // is only needed if you don't install i18n
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const resultSend = await email
|
const resultSend = await email
|
||||||
.send({
|
.send({
|
||||||
template: path.join(__dirname, 'templates', template),
|
template: path.join(__dirname, 'templates', template),
|
||||||
@ -76,38 +77,39 @@ export const sendEmailTranslated = async ({
|
|||||||
...receiver,
|
...receiver,
|
||||||
attachments: [
|
attachments: [
|
||||||
{
|
{
|
||||||
filename: 'gradido-header.jpeg',
|
// filename: 'gradido-header.jpeg',
|
||||||
path: path.join(__dirname, 'templates/includes/gradido-header.jpeg'),
|
content: gradidoHeader,
|
||||||
cid: 'gradidoheader',
|
cid: 'gradidoheader',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filename: 'facebook-icon.png',
|
// filename: 'facebook-icon.png',
|
||||||
path: path.join(__dirname, 'templates/includes/facebook-icon.png'),
|
content: facebookIcon,
|
||||||
cid: 'facebookicon',
|
cid: 'facebookicon',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filename: 'telegram-icon.png',
|
// filename: 'telegram-icon.png',
|
||||||
path: path.join(__dirname, 'templates/includes/telegram-icon.png'),
|
content: telegramIcon,
|
||||||
cid: 'telegramicon',
|
cid: 'telegramicon',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filename: 'twitter-icon.png',
|
// filename: 'twitter-icon.png',
|
||||||
path: path.join(__dirname, 'templates/includes/twitter-icon.png'),
|
content: twitterIcon,
|
||||||
cid: 'twittericon',
|
cid: 'twittericon',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filename: 'youtube-icon.png',
|
// filename: 'youtube-icon.png',
|
||||||
path: path.join(__dirname, 'templates/includes/youtube-icon.png'),
|
content: youtubeIcon,
|
||||||
cid: 'youtubeicon',
|
cid: 'youtubeicon',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filename: 'chatbox-icon.png',
|
// filename: 'chatbox-icon.png',
|
||||||
path: path.join(__dirname, 'templates/includes/chatbox-icon.png'),
|
content: chatboxIcon,
|
||||||
cid: 'chatboxicon',
|
cid: 'chatboxicon',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
locals, // the 'locale' in here seems not to be used by 'email-template', because it doesn't work if the language isn't set before by 'i18n.setLocale'
|
locals, // the 'locale' in here seems not to be used by 'email-template', because it doesn't work if the language isn't set before by 'i18n.setLocale'
|
||||||
|
// t: i18n.__.bind(i18n),
|
||||||
})
|
})
|
||||||
.catch((error: unknown) => {
|
.catch((error: unknown) => {
|
||||||
logger.error('Error sending notification email', error)
|
logger.error('Error sending notification email', error)
|
||||||
@ -1,12 +1,5 @@
|
|||||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
|
||||||
import { Decimal } from 'decimal.js-light'
|
import { Decimal } from 'decimal.js-light'
|
||||||
import { DataSource } from 'typeorm'
|
import { CONFIG } from '../config'
|
||||||
|
|
||||||
import { testEnvironment } from '@test/helpers'
|
|
||||||
import { i18n as localization } from '@test/testSetup'
|
|
||||||
import { getLogger } from 'config-schema/test/testSetup'
|
|
||||||
|
|
||||||
import { CONFIG } from '@/config'
|
|
||||||
|
|
||||||
import * as sendEmailTranslatedApi from './sendEmailTranslated'
|
import * as sendEmailTranslatedApi from './sendEmailTranslated'
|
||||||
import {
|
import {
|
||||||
@ -26,6 +19,7 @@ const testMailServerHost = 'localhost'
|
|||||||
const testMailServerPort = 1025
|
const testMailServerPort = 1025
|
||||||
const testMailTLS = false
|
const testMailTLS = false
|
||||||
|
|
||||||
|
CONFIG.EMAIL = true
|
||||||
CONFIG.EMAIL_SENDER = 'info@gradido.net'
|
CONFIG.EMAIL_SENDER = 'info@gradido.net'
|
||||||
CONFIG.EMAIL_SMTP_HOST = testMailServerHost
|
CONFIG.EMAIL_SMTP_HOST = testMailServerHost
|
||||||
CONFIG.EMAIL_SMTP_PORT = testMailServerPort
|
CONFIG.EMAIL_SMTP_PORT = testMailServerPort
|
||||||
@ -46,22 +40,6 @@ jest.mock('nodemailer', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let con: DataSource
|
|
||||||
let testEnv: {
|
|
||||||
mutate: ApolloServerTestClient['mutate']
|
|
||||||
query: ApolloServerTestClient['query']
|
|
||||||
con: DataSource
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
testEnv = await testEnvironment(getLogger('apollo'), localization)
|
|
||||||
con = testEnv.con
|
|
||||||
})
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await con.destroy()
|
|
||||||
})
|
|
||||||
|
|
||||||
const sendEmailTranslatedSpy = jest.spyOn(sendEmailTranslatedApi, 'sendEmailTranslated')
|
const sendEmailTranslatedSpy = jest.spyOn(sendEmailTranslatedApi, 'sendEmailTranslated')
|
||||||
|
|
||||||
describe('sendEmailVariants', () => {
|
describe('sendEmailVariants', () => {
|
||||||
@ -91,24 +69,26 @@ describe('sendEmailVariants', () => {
|
|||||||
to: 'Peter Lustig <peter@lustig.de>',
|
to: 'Peter Lustig <peter@lustig.de>',
|
||||||
},
|
},
|
||||||
template: 'addedContributionMessage',
|
template: 'addedContributionMessage',
|
||||||
locals: {
|
locals: expect.objectContaining({
|
||||||
firstName: 'Peter',
|
firstName: 'Peter',
|
||||||
lastName: 'Lustig',
|
lastName: 'Lustig',
|
||||||
locale: 'en',
|
language: 'en',
|
||||||
senderFirstName: 'Bibi',
|
senderFirstName: 'Bibi',
|
||||||
senderLastName: 'Bloxberg',
|
senderLastName: 'Bloxberg',
|
||||||
contributionMemo: 'My contribution.',
|
contributionMemo: 'My contribution.',
|
||||||
contributionFrontendLink,
|
contributionFrontendLink,
|
||||||
message: 'My message.',
|
message: 'My message.',
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
||||||
},
|
}),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('result', () => {
|
describe('result', () => {
|
||||||
it('is the expected object', () => {
|
it('is the expected object', () => {
|
||||||
expect(result).toMatchObject({
|
// bun testrunner bug, toMatchObject mess with 'result'
|
||||||
|
const resultClone = JSON.parse(JSON.stringify(result))
|
||||||
|
expect(resultClone).toMatchObject({
|
||||||
originalMessage: expect.objectContaining({
|
originalMessage: expect.objectContaining({
|
||||||
to: 'Peter Lustig <peter@lustig.de>',
|
to: 'Peter Lustig <peter@lustig.de>',
|
||||||
from: 'Gradido (emails.general.doNotAnswer) <info@gradido.net>',
|
from: 'Gradido (emails.general.doNotAnswer) <info@gradido.net>',
|
||||||
@ -145,23 +125,26 @@ describe('sendEmailVariants', () => {
|
|||||||
to: 'Peter Lustig <peter@lustig.de>',
|
to: 'Peter Lustig <peter@lustig.de>',
|
||||||
},
|
},
|
||||||
template: 'accountActivation',
|
template: 'accountActivation',
|
||||||
locals: {
|
locals: expect.objectContaining({
|
||||||
firstName: 'Peter',
|
firstName: 'Peter',
|
||||||
lastName: 'Lustig',
|
lastName: 'Lustig',
|
||||||
locale: 'en',
|
language: 'en',
|
||||||
activationLink: 'http://localhost/checkEmail/6627633878930542284',
|
activationLink: 'http://localhost/checkEmail/6627633878930542284',
|
||||||
timeDurationObject: { hours: 23, minutes: 30 },
|
timeDurationObject: { hours: 23, minutes: 30 },
|
||||||
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
||||||
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
||||||
communityURL: CONFIG.COMMUNITY_URL,
|
communityURL: CONFIG.COMMUNITY_URL,
|
||||||
},
|
}),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
describe('result', () => {
|
describe('result', () => {
|
||||||
it('is the expected object', () => {
|
it('is the expected object', () => {
|
||||||
expect(result).toMatchObject({
|
// bun testrunner bug, toMatchObject mess with 'result'
|
||||||
|
const resultClone = JSON.parse(JSON.stringify(result))
|
||||||
|
expect(resultClone).toMatchObject({
|
||||||
originalMessage: expect.objectContaining({
|
originalMessage: expect.objectContaining({
|
||||||
to: 'Peter Lustig <peter@lustig.de>',
|
to: 'Peter Lustig <peter@lustig.de>',
|
||||||
from: 'Gradido (emails.general.doNotAnswer) <info@gradido.net>',
|
from: 'Gradido (emails.general.doNotAnswer) <info@gradido.net>',
|
||||||
@ -179,6 +162,8 @@ describe('sendEmailVariants', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
describe('sendAccountMultiRegistrationEmail', () => {
|
describe('sendAccountMultiRegistrationEmail', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
result = await sendAccountMultiRegistrationEmail({
|
result = await sendAccountMultiRegistrationEmail({
|
||||||
@ -620,4 +605,5 @@ describe('sendEmailVariants', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
})
|
})
|
||||||
179
core/src/emails/sendEmailVariants.ts
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import { Decimal } from 'decimal.js-light'
|
||||||
|
|
||||||
|
import { CONFIG } from '../config'
|
||||||
|
import { decimalSeparatorByLanguage } from '../util/utilities'
|
||||||
|
|
||||||
|
import { sendEmailTranslated } from './sendEmailTranslated'
|
||||||
|
|
||||||
|
export interface EmailCommonData {
|
||||||
|
firstName: string
|
||||||
|
lastName: string
|
||||||
|
email: string
|
||||||
|
language: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContributionEmailCommonData {
|
||||||
|
senderFirstName: string
|
||||||
|
senderLastName: string
|
||||||
|
contributionMemo: string
|
||||||
|
contributionFrontendLink: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEmailCommonLocales(): Record<string, unknown> {
|
||||||
|
return {
|
||||||
|
supportEmail: CONFIG.COMMUNITY_SUPPORT_MAIL,
|
||||||
|
resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD,
|
||||||
|
communityURL: CONFIG.COMMUNITY_URL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendAddedContributionMessageEmail = (
|
||||||
|
data: EmailCommonData & ContributionEmailCommonData & {
|
||||||
|
message: string
|
||||||
|
},
|
||||||
|
): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: {
|
||||||
|
to: `${data.firstName} ${data.lastName} <${data.email}>`,
|
||||||
|
},
|
||||||
|
template: 'addedContributionMessage',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendAccountActivationEmail = (data: EmailCommonData & {
|
||||||
|
activationLink: string
|
||||||
|
timeDurationObject: Record<string, unknown>
|
||||||
|
logoUrl?: string | null
|
||||||
|
}): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'accountActivation',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendAccountMultiRegistrationEmail = (data: EmailCommonData): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'accountMultiRegistration',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendContributionConfirmedEmail = (
|
||||||
|
data: EmailCommonData & ContributionEmailCommonData & {
|
||||||
|
contributionAmount: Decimal
|
||||||
|
},
|
||||||
|
): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'contributionConfirmed',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
contributionAmount: decimalSeparatorByLanguage(data.contributionAmount, data.language),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendContributionChangedByModeratorEmail = (
|
||||||
|
data: EmailCommonData & ContributionEmailCommonData & {
|
||||||
|
contributionMemoUpdated: string
|
||||||
|
},
|
||||||
|
): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'contributionChangedByModerator',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
contributionMemoUpdated: data.contributionMemoUpdated,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendContributionDeletedEmail = (
|
||||||
|
data: EmailCommonData & ContributionEmailCommonData,
|
||||||
|
): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'contributionDeleted',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendContributionDeniedEmail = (
|
||||||
|
data: EmailCommonData & ContributionEmailCommonData,
|
||||||
|
): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'contributionDenied',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendResetPasswordEmail = (data: EmailCommonData & {
|
||||||
|
resetLink: string
|
||||||
|
timeDurationObject: Record<string, unknown>
|
||||||
|
}): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'resetPassword',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendTransactionLinkRedeemedEmail = (data: EmailCommonData & {
|
||||||
|
senderFirstName: string
|
||||||
|
senderLastName: string
|
||||||
|
senderEmail: string
|
||||||
|
transactionMemo: string
|
||||||
|
transactionAmount: Decimal
|
||||||
|
}): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'transactionLinkRedeemed',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
transactionAmount: decimalSeparatorByLanguage(data.transactionAmount, data.language),
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sendTransactionReceivedEmail = (data: EmailCommonData & {
|
||||||
|
senderFirstName: string
|
||||||
|
senderLastName: string
|
||||||
|
senderEmail: string
|
||||||
|
memo: string
|
||||||
|
transactionAmount: Decimal
|
||||||
|
}): Promise<Record<string, unknown> | boolean | null | Error> => {
|
||||||
|
return sendEmailTranslated({
|
||||||
|
receiver: { to: `${data.firstName} ${data.lastName} <${data.email}>` },
|
||||||
|
template: 'transactionReceived',
|
||||||
|
locals: {
|
||||||
|
...data,
|
||||||
|
transactionAmount: decimalSeparatorByLanguage(data.transactionAmount, data.language),
|
||||||
|
...getEmailCommonLocales(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |