mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into alias-update-user-info
This commit is contained in:
commit
e83c06a419
@ -1,3 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
build/
|
||||||
coverage/
|
coverage/
|
||||||
2
admin/.gitignore
vendored
2
admin/.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
build/
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
/.env
|
/.env
|
||||||
|
|||||||
@ -84,7 +84,7 @@ CMD /bin/sh -c "yarn run dev"
|
|||||||
FROM base as production
|
FROM base as production
|
||||||
|
|
||||||
# Copy "binary"-files from build image
|
# Copy "binary"-files from build image
|
||||||
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
|
COPY --from=build ${DOCKER_WORKDIR}/build ./build
|
||||||
# We also copy the node_modules express and serve-static for the run script
|
# We also copy the node_modules express and serve-static for the run script
|
||||||
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||||
# Copy static files
|
# Copy static files
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
"serve": "vue-cli-service serve --open",
|
"serve": "vue-cli-service serve --open",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"dev": "yarn run serve",
|
"dev": "yarn run serve",
|
||||||
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
|
"analyse-bundle": "yarn build && webpack-bundle-analyzer build/webpack.stats.json",
|
||||||
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
|
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
|
||||||
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
|
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
|
||||||
"test": "cross-env TZ=UTC jest",
|
"test": "cross-env TZ=UTC jest",
|
||||||
|
|||||||
@ -9,10 +9,10 @@ const port = process.env.PORT || 8080
|
|||||||
// Express Server
|
// Express Server
|
||||||
const app = express()
|
const app = express()
|
||||||
// Serve files
|
// Serve files
|
||||||
app.use(express.static(path.join(__dirname, '../dist')))
|
app.use(express.static(path.join(__dirname, '../build')))
|
||||||
// Default to index.html
|
// Default to index.html
|
||||||
app.get('*', (req, res) => {
|
app.get('*', (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, '../dist/index.html'))
|
res.sendFile(path.join(__dirname, '../build/index.html'))
|
||||||
})
|
})
|
||||||
|
|
||||||
app.listen(port, hostname, () => {
|
app.listen(port, hostname, () => {
|
||||||
|
|||||||
@ -37,6 +37,7 @@ export const actions = {
|
|||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
plugins: [
|
plugins: [
|
||||||
createPersistedState({
|
createPersistedState({
|
||||||
|
key: 'gradido-admin',
|
||||||
storage: window.localStorage,
|
storage: window.localStorage,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -49,5 +49,5 @@ module.exports = {
|
|||||||
// Enable CSS source maps.
|
// Enable CSS source maps.
|
||||||
sourceMap: CONFIG.NODE_ENV !== 'production',
|
sourceMap: CONFIG.NODE_ENV !== 'production',
|
||||||
},
|
},
|
||||||
outputDir: path.resolve(__dirname, './dist'),
|
outputDir: path.resolve(__dirname, './build'),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
**/*.min.js
|
**/*.min.js
|
||||||
build
|
build
|
||||||
|
coverage
|
||||||
@ -12,6 +12,8 @@ module.exports = {
|
|||||||
'plugin:prettier/recommended',
|
'plugin:prettier/recommended',
|
||||||
'plugin:import/recommended',
|
'plugin:import/recommended',
|
||||||
'plugin:import/typescript',
|
'plugin:import/typescript',
|
||||||
|
'plugin:security/recommended',
|
||||||
|
'plugin:@eslint-community/eslint-comments/recommended',
|
||||||
],
|
],
|
||||||
settings: {
|
settings: {
|
||||||
'import/parsers': {
|
'import/parsers': {
|
||||||
@ -151,6 +153,11 @@ module.exports = {
|
|||||||
'promise/valid-params': 'warn',
|
'promise/valid-params': 'warn',
|
||||||
'promise/prefer-await-to-callbacks': 'error',
|
'promise/prefer-await-to-callbacks': 'error',
|
||||||
'promise/no-multiple-resolved': 'error',
|
'promise/no-multiple-resolved': 'error',
|
||||||
|
// eslint comments
|
||||||
|
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
|
||||||
|
'@eslint-community/eslint-comments/no-restricted-disable': 'error',
|
||||||
|
'@eslint-community/eslint-comments/no-use': 'off',
|
||||||
|
'@eslint-community/eslint-comments/require-description': 'off',
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
// only for ts files
|
// only for ts files
|
||||||
@ -159,6 +166,7 @@ module.exports = {
|
|||||||
extends: [
|
extends: [
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||||
|
'plugin:@typescript-eslint/strict',
|
||||||
'plugin:type-graphql/recommended',
|
'plugin:type-graphql/recommended',
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
@ -169,6 +177,8 @@ module.exports = {
|
|||||||
'@typescript-eslint/prefer-regexp-exec': 'off',
|
'@typescript-eslint/prefer-regexp-exec': 'off',
|
||||||
// this should not run on ts files: https://github.com/import-js/eslint-plugin-import/issues/2215#issuecomment-911245486
|
// this should not run on ts files: https://github.com/import-js/eslint-plugin-import/issues/2215#issuecomment-911245486
|
||||||
'import/unambiguous': 'off',
|
'import/unambiguous': 'off',
|
||||||
|
// this is not compatible with typeorm, due to joined tables can be null, but are not defined as nullable
|
||||||
|
'@typescript-eslint/no-unnecessary-condition': 'off',
|
||||||
},
|
},
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ module.exports = {
|
|||||||
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!src/seeds/**', '!build/**'],
|
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!src/seeds/**', '!build/**'],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
lines: 85,
|
lines: 86,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setupFiles: ['<rootDir>/test/testSetup.ts'],
|
setupFiles: ['<rootDir>/test/testSetup.ts'],
|
||||||
|
|||||||
@ -46,6 +46,7 @@
|
|||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint-community/eslint-plugin-eslint-comments": "^3.2.1",
|
||||||
"@types/email-templates": "^10.0.1",
|
"@types/email-templates": "^10.0.1",
|
||||||
"@types/express": "^4.17.12",
|
"@types/express": "^4.17.12",
|
||||||
"@types/faker": "^5.5.9",
|
"@types/faker": "^5.5.9",
|
||||||
@ -68,6 +69,7 @@
|
|||||||
"eslint-plugin-n": "^15.7.0",
|
"eslint-plugin-n": "^15.7.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-promise": "^6.1.1",
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
|
"eslint-plugin-security": "^1.7.1",
|
||||||
"eslint-plugin-type-graphql": "^1.0.0",
|
"eslint-plugin-type-graphql": "^1.0.0",
|
||||||
"faker": "^5.5.3",
|
"faker": "^5.5.3",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import axios from 'axios'
|
|||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
import { backendLogger as logger } from '@/server/logger'
|
import { backendLogger as logger } from '@/server/logger'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
export const apiPost = async (url: string, payload: unknown): Promise<any> => {
|
export const apiPost = async (url: string, payload: unknown): Promise<any> => {
|
||||||
logger.trace('POST', url, payload)
|
logger.trace('POST', url, payload)
|
||||||
try {
|
try {
|
||||||
@ -25,7 +24,6 @@ export const apiPost = async (url: string, payload: unknown): Promise<any> => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
export const apiGet = async (url: string): Promise<any> => {
|
export const apiGet = async (url: string): Promise<any> => {
|
||||||
logger.trace('GET: url=' + url)
|
logger.trace('GET: url=' + url)
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import KlicktippConnector from 'klicktipp-api'
|
|||||||
|
|
||||||
const klicktippConnector = new KlicktippConnector()
|
const klicktippConnector = new KlicktippConnector()
|
||||||
|
|
||||||
export const klicktippSignIn = async (
|
export const subscribe = async (
|
||||||
email: string,
|
email: string,
|
||||||
language: string,
|
language: string,
|
||||||
firstName?: string,
|
firstName?: string,
|
||||||
@ -28,13 +28,6 @@ export const klicktippSignIn = async (
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export const signout = async (email: string, language: string): Promise<boolean> => {
|
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
|
||||||
const apiKey = language === 'de' ? CONFIG.KLICKTIPP_APIKEY_DE : CONFIG.KLICKTIPP_APIKEY_EN
|
|
||||||
const result = await klicktippConnector.signoff(apiKey, email)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
export const unsubscribe = async (email: string): Promise<boolean> => {
|
export const unsubscribe = async (email: string): Promise<boolean> => {
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
if (!CONFIG.KLICKTIPP) return true
|
||||||
const isLogin = await loginKlicktippUser()
|
const isLogin = await loginKlicktippUser()
|
||||||
@ -60,38 +53,6 @@ export const loginKlicktippUser = async (): Promise<boolean> => {
|
|||||||
return await klicktippConnector.login(CONFIG.KLICKTIPP_USER, CONFIG.KLICKTIPP_PASSWORD)
|
return await klicktippConnector.login(CONFIG.KLICKTIPP_USER, CONFIG.KLICKTIPP_PASSWORD)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const logoutKlicktippUser = async (): Promise<boolean> => {
|
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
|
||||||
return await klicktippConnector.logout()
|
|
||||||
}
|
|
||||||
|
|
||||||
export const untagUser = async (email: string, tagId: string): Promise<boolean> => {
|
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
|
||||||
const isLogin = await loginKlicktippUser()
|
|
||||||
if (isLogin) {
|
|
||||||
return await klicktippConnector.untag(email, tagId)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
export const tagUser = async (email: string, tagIds: string): Promise<boolean> => {
|
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
|
||||||
const isLogin = await loginKlicktippUser()
|
|
||||||
if (isLogin) {
|
|
||||||
return await klicktippConnector.tag(email, tagIds)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getKlicktippTagMap = async () => {
|
|
||||||
if (!CONFIG.KLICKTIPP) return true
|
|
||||||
const isLogin = await loginKlicktippUser()
|
|
||||||
if (isLogin) {
|
|
||||||
return await klicktippConnector.tagIndex()
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
export const addFieldsToSubscriber = async (
|
export const addFieldsToSubscriber = async (
|
||||||
email: string,
|
email: string,
|
||||||
fields: any = {},
|
fields: any = {},
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { CustomJwtPayload } from './CustomJwtPayload'
|
|||||||
export const decode = (token: string): CustomJwtPayload | null => {
|
export const decode = (token: string): CustomJwtPayload | null => {
|
||||||
if (!token) throw new LogError('401 Unauthorized')
|
if (!token) throw new LogError('401 Unauthorized')
|
||||||
try {
|
try {
|
||||||
return <CustomJwtPayload>verify(token, CONFIG.JWT_SECRET)
|
return verify(token, CONFIG.JWT_SECRET) as CustomJwtPayload
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ const constants = {
|
|||||||
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||||
LOG4JS_CONFIG: 'log4js-config.json',
|
LOG4JS_CONFIG: 'log4js-config.json',
|
||||||
// default log level on production should be info
|
// default log level on production should be info
|
||||||
LOG_LEVEL: process.env.LOG_LEVEL || 'info',
|
LOG_LEVEL: process.env.LOG_LEVEL ?? 'info',
|
||||||
CONFIG_VERSION: {
|
CONFIG_VERSION: {
|
||||||
DEFAULT: 'DEFAULT',
|
DEFAULT: 'DEFAULT',
|
||||||
EXPECTED: 'v15.2023-02-07',
|
EXPECTED: 'v15.2023-02-07',
|
||||||
@ -25,67 +25,67 @@ const constants = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const server = {
|
const server = {
|
||||||
PORT: process.env.PORT || 4000,
|
PORT: process.env.PORT ?? 4000,
|
||||||
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',
|
||||||
GRAPHIQL: process.env.GRAPHIQL === 'true' || false,
|
GRAPHIQL: process.env.GRAPHIQL === 'true' || false,
|
||||||
GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net',
|
GDT_API_URL: process.env.GDT_API_URL ?? 'https://gdt.gradido.net',
|
||||||
PRODUCTION: process.env.NODE_ENV === 'production' || false,
|
PRODUCTION: process.env.NODE_ENV === 'production' || false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const database = {
|
const database = {
|
||||||
DB_HOST: process.env.DB_HOST || 'localhost',
|
DB_HOST: process.env.DB_HOST ?? 'localhost',
|
||||||
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
|
DB_PORT: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306,
|
||||||
DB_USER: process.env.DB_USER || 'root',
|
DB_USER: process.env.DB_USER ?? 'root',
|
||||||
DB_PASSWORD: process.env.DB_PASSWORD || '',
|
DB_PASSWORD: process.env.DB_PASSWORD ?? '',
|
||||||
DB_DATABASE: process.env.DB_DATABASE || 'gradido_community',
|
DB_DATABASE: process.env.DB_DATABASE ?? 'gradido_community',
|
||||||
TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.backend.log',
|
TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH ?? 'typeorm.backend.log',
|
||||||
}
|
}
|
||||||
|
|
||||||
const klicktipp = {
|
const klicktipp = {
|
||||||
KLICKTIPP: process.env.KLICKTIPP === 'true' || false,
|
KLICKTIPP: process.env.KLICKTIPP === 'true' || false,
|
||||||
KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL || 'https://api.klicktipp.com',
|
KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL ?? 'https://api.klicktipp.com',
|
||||||
KLICKTIPP_USER: process.env.KLICKTIPP_USER || 'gradido_test',
|
KLICKTIPP_USER: process.env.KLICKTIPP_USER ?? 'gradido_test',
|
||||||
KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD || 'secret321',
|
KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD ?? 'secret321',
|
||||||
KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE || 'SomeFakeKeyDE',
|
KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE ?? 'SomeFakeKeyDE',
|
||||||
KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN || 'SomeFakeKeyEN',
|
KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN ?? 'SomeFakeKeyEN',
|
||||||
}
|
}
|
||||||
|
|
||||||
const community = {
|
const community = {
|
||||||
COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung',
|
COMMUNITY_NAME: process.env.COMMUNITY_NAME ?? 'Gradido Entwicklung',
|
||||||
COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/',
|
COMMUNITY_URL: process.env.COMMUNITY_URL ?? 'http://localhost/',
|
||||||
COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL || 'http://localhost/register',
|
COMMUNITY_REGISTER_URL: process.env.COMMUNITY_REGISTER_URL ?? 'http://localhost/register',
|
||||||
COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL || 'http://localhost/redeem/{code}',
|
COMMUNITY_REDEEM_URL: process.env.COMMUNITY_REDEEM_URL ?? 'http://localhost/redeem/{code}',
|
||||||
COMMUNITY_REDEEM_CONTRIBUTION_URL:
|
COMMUNITY_REDEEM_CONTRIBUTION_URL:
|
||||||
process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL || 'http://localhost/redeem/CL-{code}',
|
process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL ?? 'http://localhost/redeem/CL-{code}',
|
||||||
COMMUNITY_DESCRIPTION:
|
COMMUNITY_DESCRIPTION:
|
||||||
process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.',
|
process.env.COMMUNITY_DESCRIPTION ?? 'Die lokale Entwicklungsumgebung von Gradido.',
|
||||||
COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL || 'support@supportmail.com',
|
COMMUNITY_SUPPORT_MAIL: process.env.COMMUNITY_SUPPORT_MAIL ?? 'support@supportmail.com',
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginServer = {
|
const loginServer = {
|
||||||
LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe',
|
LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET ?? '21ffbbc616fe',
|
||||||
LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a',
|
LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY ?? 'a51ef8ac7ef1abf162fb7a65261acd7a',
|
||||||
}
|
}
|
||||||
|
|
||||||
const email = {
|
const email = {
|
||||||
EMAIL: process.env.EMAIL === 'true' || false,
|
EMAIL: process.env.EMAIL === 'true' || false,
|
||||||
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' || false,
|
EMAIL_TEST_MODUS: process.env.EMAIL_TEST_MODUS === 'true' || false,
|
||||||
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER || 'stage1@gradido.net',
|
EMAIL_TEST_RECEIVER: process.env.EMAIL_TEST_RECEIVER ?? 'stage1@gradido.net',
|
||||||
EMAIL_USERNAME: process.env.EMAIL_USERNAME || '',
|
EMAIL_USERNAME: process.env.EMAIL_USERNAME ?? '',
|
||||||
EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net',
|
EMAIL_SENDER: process.env.EMAIL_SENDER ?? 'info@gradido.net',
|
||||||
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || '',
|
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD ?? '',
|
||||||
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'mailserver',
|
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL ?? 'mailserver',
|
||||||
EMAIL_SMTP_PORT: Number(process.env.EMAIL_SMTP_PORT) || 1025,
|
EMAIL_SMTP_PORT: Number(process.env.EMAIL_SMTP_PORT) || 1025,
|
||||||
// eslint-disable-next-line no-unneeded-ternary
|
// eslint-disable-next-line no-unneeded-ternary
|
||||||
EMAIL_TLS: process.env.EMAIL_TLS === 'false' ? false : true,
|
EMAIL_TLS: process.env.EMAIL_TLS === 'false' ? false : true,
|
||||||
EMAIL_LINK_VERIFICATION:
|
EMAIL_LINK_VERIFICATION:
|
||||||
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}',
|
process.env.EMAIL_LINK_VERIFICATION ?? 'http://localhost/checkEmail/{optin}{code}',
|
||||||
EMAIL_LINK_SETPASSWORD:
|
EMAIL_LINK_SETPASSWORD:
|
||||||
process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}',
|
process.env.EMAIL_LINK_SETPASSWORD ?? 'http://localhost/reset-password/{optin}',
|
||||||
EMAIL_LINK_FORGOTPASSWORD:
|
EMAIL_LINK_FORGOTPASSWORD:
|
||||||
process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password',
|
process.env.EMAIL_LINK_FORGOTPASSWORD ?? 'http://localhost/forgot-password',
|
||||||
EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview',
|
EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW ?? 'http://localhost/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
|
||||||
? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440
|
? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440
|
||||||
@ -98,14 +98,14 @@ const email = {
|
|||||||
|
|
||||||
const webhook = {
|
const webhook = {
|
||||||
// Elopage
|
// Elopage
|
||||||
WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret',
|
WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET ?? 'secret',
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is needed by graphql-directive-auth
|
// This is needed by graphql-directive-auth
|
||||||
process.env.APP_SECRET = server.JWT_SECRET
|
process.env.APP_SECRET = server.JWT_SECRET
|
||||||
|
|
||||||
// Check config version
|
// Check config version
|
||||||
constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION || constants.CONFIG_VERSION.DEFAULT
|
constants.CONFIG_VERSION.CURRENT = process.env.CONFIG_VERSION ?? constants.CONFIG_VERSION.DEFAULT
|
||||||
if (
|
if (
|
||||||
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
|
![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes(
|
||||||
constants.CONFIG_VERSION.CURRENT,
|
constants.CONFIG_VERSION.CURRENT,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { GraphQLClient } from 'graphql-request'
|
import { GraphQLClient } from 'graphql-request'
|
||||||
import { PatchedRequestInit } from 'graphql-request/dist/types'
|
import { PatchedRequestInit } from 'graphql-request/dist/types'
|
||||||
|
|
||||||
type ClientInstance = {
|
interface ClientInstance {
|
||||||
url: string
|
url: string
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
client: GraphQLGetClient
|
client: GraphQLGetClient
|
||||||
|
|||||||
@ -54,7 +54,7 @@ export async function validateCommunities(): Promise<void> {
|
|||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Federation: received not matching publicKey -> received: ${
|
`Federation: received not matching publicKey -> received: ${
|
||||||
pubKey || 'null'
|
pubKey ?? 'null'
|
||||||
}, expected: ${dbCom.publicKey.toString()} `,
|
}, expected: ${dbCom.publicKey.toString()} `,
|
||||||
)
|
)
|
||||||
// DbCommunity.delete({ id: dbCom.id })
|
// DbCommunity.delete({ id: dbCom.id })
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) =>
|
|||||||
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
context.role = ROLE_UNAUTHORIZED // unauthorized user
|
||||||
|
|
||||||
// is rights an inalienable right?
|
// is rights an inalienable right?
|
||||||
if ((<RIGHTS[]>rights).reduce((acc, right) => acc && INALIENABLE_RIGHTS.includes(right), true))
|
if ((rights as RIGHTS[]).reduce((acc, right) => acc && INALIENABLE_RIGHTS.includes(right), true))
|
||||||
return true
|
return true
|
||||||
|
|
||||||
// Do we have a token?
|
// Do we have a token?
|
||||||
@ -43,7 +43,7 @@ export const isAuthorized: AuthChecker<Context> = async ({ context }, rights) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for correct rights
|
// check for correct rights
|
||||||
const missingRights = (<RIGHTS[]>rights).filter((right) => !context.role?.hasRight(right))
|
const missingRights = (rights as RIGHTS[]).filter((right) => !context.role?.hasRight(right))
|
||||||
if (missingRights.length !== 0) {
|
if (missingRights.length !== 0) {
|
||||||
throw new LogError('401 Unauthorized')
|
throw new LogError('401 Unauthorized')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export class Balance {
|
|||||||
linkCount: number
|
linkCount: number
|
||||||
}) {
|
}) {
|
||||||
this.balance = data.balance
|
this.balance = data.balance
|
||||||
this.balanceGDT = data.balanceGDT || null
|
this.balanceGDT = data.balanceGDT ?? null
|
||||||
this.count = data.count
|
this.count = data.count
|
||||||
this.linkCount = data.linkCount
|
this.linkCount = data.linkCount
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,13 +43,12 @@ export class Transaction {
|
|||||||
this.memo = transaction.memo
|
this.memo = transaction.memo
|
||||||
this.creationDate = transaction.creationDate
|
this.creationDate = transaction.creationDate
|
||||||
this.linkedUser = linkedUser
|
this.linkedUser = linkedUser
|
||||||
this.linkedTransactionId = transaction.linkedTransactionId || null
|
this.linkedTransactionId = transaction.linkedTransactionId ?? null
|
||||||
this.linkId = transaction.contribution
|
this.linkId = transaction.contribution
|
||||||
? transaction.contribution.contributionLinkId
|
? transaction.contribution.contributionLinkId
|
||||||
: transaction.transactionLinkId || null
|
: transaction.transactionLinkId ?? null
|
||||||
this.previousBalance =
|
this.previousBalance =
|
||||||
(transaction.previousTransaction &&
|
transaction.previousTransaction?.balance.toDecimalPlaces(2, Decimal.ROUND_DOWN) ??
|
||||||
transaction.previousTransaction.balance.toDecimalPlaces(2, Decimal.ROUND_DOWN)) ||
|
|
||||||
new Decimal(0)
|
new Decimal(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,10 @@ export class BalanceResolver {
|
|||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
`calculatedDecay(balance=${lastTransaction.balance}, balanceDate=${lastTransaction.balanceDate})=${calculatedDecay}`,
|
'calculatedDecay',
|
||||||
|
lastTransaction.balance,
|
||||||
|
lastTransaction.balanceDate,
|
||||||
|
calculatedDecay,
|
||||||
)
|
)
|
||||||
|
|
||||||
// The final balance is reduced by the link amount withheld
|
// The final balance is reduced by the link amount withheld
|
||||||
@ -96,9 +99,7 @@ export class BalanceResolver {
|
|||||||
count,
|
count,
|
||||||
linkCount,
|
linkCount,
|
||||||
})
|
})
|
||||||
logger.info(
|
logger.info('new Balance', balance, balanceGDT, count, linkCount, newBalance)
|
||||||
`new Balance(balance=${balance}, balanceGDT=${balanceGDT}, count=${count}, linkCount=${linkCount}) = ${newBalance}`,
|
|
||||||
)
|
|
||||||
|
|
||||||
return newBalance
|
return newBalance
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ let testEnv: {
|
|||||||
query: ApolloServerTestClient['query']
|
query: ApolloServerTestClient['query']
|
||||||
con: Connection
|
con: Connection
|
||||||
}
|
}
|
||||||
let creation: Contribution | void
|
let creation: Contribution | null
|
||||||
let admin: User
|
let admin: User
|
||||||
let pendingContribution: any
|
let pendingContribution: any
|
||||||
let inProgressContribution: any
|
let inProgressContribution: any
|
||||||
@ -2071,7 +2071,7 @@ describe('ContributionResolver', () => {
|
|||||||
mutate({
|
mutate({
|
||||||
mutation: updateContribution,
|
mutation: updateContribution,
|
||||||
variables: {
|
variables: {
|
||||||
contributionId: (adminContribution && adminContribution.id) || -1,
|
contributionId: adminContribution?.id ?? -1,
|
||||||
amount: 100.0,
|
amount: 100.0,
|
||||||
memo: 'Test Test Test',
|
memo: 'Test Test Test',
|
||||||
creationDate: new Date().toString(),
|
creationDate: new Date().toString(),
|
||||||
@ -2565,8 +2565,8 @@ describe('ContributionResolver', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('confirm two creations one after the other quickly', () => {
|
describe('confirm two creations one after the other quickly', () => {
|
||||||
let c1: Contribution | void
|
let c1: Contribution | null
|
||||||
let c2: Contribution | void
|
let c2: Contribution | null
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|||||||
@ -269,7 +269,7 @@ export class ContributionResolver {
|
|||||||
withDeleted: true,
|
withDeleted: true,
|
||||||
relations: ['user'],
|
relations: ['user'],
|
||||||
})
|
})
|
||||||
if (!emailContact || !emailContact.user) {
|
if (!emailContact?.user) {
|
||||||
throw new LogError('Could not find user', email)
|
throw new LogError('Could not find user', email)
|
||||||
}
|
}
|
||||||
if (emailContact.deletedAt || emailContact.user.deletedAt) {
|
if (emailContact.deletedAt || emailContact.user.deletedAt) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Resolver, Authorized, Mutation, Ctx } from 'type-graphql'
|
import { Resolver, Authorized, Mutation, Ctx } from 'type-graphql'
|
||||||
|
|
||||||
import { unsubscribe, klicktippSignIn } from '@/apis/KlicktippController'
|
import { unsubscribe, subscribe } from '@/apis/KlicktippController'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { EVENT_NEWSLETTER_SUBSCRIBE, EVENT_NEWSLETTER_UNSUBSCRIBE } from '@/event/Events'
|
import { EVENT_NEWSLETTER_SUBSCRIBE, EVENT_NEWSLETTER_UNSUBSCRIBE } from '@/event/Events'
|
||||||
import { Context, getUser } from '@/server/context'
|
import { Context, getUser } from '@/server/context'
|
||||||
@ -20,6 +20,6 @@ export class KlicktippResolver {
|
|||||||
async subscribeNewsletter(@Ctx() context: Context): Promise<boolean> {
|
async subscribeNewsletter(@Ctx() context: Context): Promise<boolean> {
|
||||||
const user = getUser(context)
|
const user = getUser(context)
|
||||||
await EVENT_NEWSLETTER_SUBSCRIBE(user)
|
await EVENT_NEWSLETTER_SUBSCRIBE(user)
|
||||||
return klicktippSignIn(user.emailContact.email, user.language)
|
return subscribe(user.emailContact.email, user.language)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -817,8 +817,8 @@ describe('TransactionLinkResolver', () => {
|
|||||||
const bibisTransaktionLinks = transactionLinks.filter(
|
const bibisTransaktionLinks = transactionLinks.filter(
|
||||||
(transactionLink) => transactionLink.email === 'bibi@bloxberg.de',
|
(transactionLink) => transactionLink.email === 'bibi@bloxberg.de',
|
||||||
)
|
)
|
||||||
for (let i = 0; i < bibisTransaktionLinks.length; i++) {
|
for (const bibisTransaktionLink of bibisTransaktionLinks) {
|
||||||
await transactionLinkFactory(testEnv, bibisTransaktionLinks[i])
|
await transactionLinkFactory(testEnv, bibisTransaktionLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
// admin: only now log in
|
// admin: only now log in
|
||||||
@ -1040,6 +1040,7 @@ describe('TransactionLinkResolver', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('returns a string that ends with the hex value of date', () => {
|
it('returns a string that ends with the hex value of date', () => {
|
||||||
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
||||||
const regexp = new RegExp(date.getTime().toString(16) + '$')
|
const regexp = new RegExp(date.getTime().toString(16) + '$')
|
||||||
expect(transactionLinkCode(date)).toEqual(expect.stringMatching(regexp))
|
expect(transactionLinkCode(date)).toEqual(expect.stringMatching(regexp))
|
||||||
})
|
})
|
||||||
|
|||||||
@ -146,7 +146,7 @@ export class TransactionLinkResolver {
|
|||||||
const transactionLink = await DbTransactionLink.findOneOrFail({ code }, { withDeleted: true })
|
const transactionLink = await DbTransactionLink.findOneOrFail({ code }, { withDeleted: true })
|
||||||
const user = await DbUser.findOneOrFail({ id: transactionLink.userId })
|
const user = await DbUser.findOneOrFail({ id: transactionLink.userId })
|
||||||
let redeemedBy: User | null = null
|
let redeemedBy: User | null = null
|
||||||
if (transactionLink && transactionLink.redeemedBy) {
|
if (transactionLink?.redeemedBy) {
|
||||||
redeemedBy = new User(await DbUser.findOneOrFail({ id: transactionLink.redeemedBy }))
|
redeemedBy = new User(await DbUser.findOneOrFail({ id: transactionLink.redeemedBy }))
|
||||||
}
|
}
|
||||||
return new TransactionLink(transactionLink, new User(user), redeemedBy)
|
return new TransactionLink(transactionLink, new User(user), redeemedBy)
|
||||||
|
|||||||
@ -48,9 +48,7 @@ export const executeTransaction = async (
|
|||||||
// acquire lock
|
// acquire lock
|
||||||
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
const releaseLock = await TRANSACTIONS_LOCK.acquire()
|
||||||
try {
|
try {
|
||||||
logger.info(
|
logger.info('executeTransaction', amount, memo, sender, recipient)
|
||||||
`executeTransaction(amount=${amount}, memo=${memo}, sender=${sender}, recipient=${recipient})...`,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (sender.id === recipient.id) {
|
if (sender.id === recipient.id) {
|
||||||
throw new LogError('Sender and Recipient are the same', sender.id)
|
throw new LogError('Sender and Recipient are the same', sender.id)
|
||||||
@ -119,10 +117,10 @@ export const executeTransaction = async (
|
|||||||
// Save linked transaction id for send
|
// Save linked transaction id for send
|
||||||
transactionSend.linkedTransactionId = transactionReceive.id
|
transactionSend.linkedTransactionId = transactionReceive.id
|
||||||
await queryRunner.manager.update(dbTransaction, { id: transactionSend.id }, transactionSend)
|
await queryRunner.manager.update(dbTransaction, { id: transactionSend.id }, transactionSend)
|
||||||
logger.debug(`send Transaction updated: ${transactionSend}`)
|
logger.debug('send Transaction updated', transactionSend)
|
||||||
|
|
||||||
if (transactionLink) {
|
if (transactionLink) {
|
||||||
logger.info(`transactionLink: ${transactionLink}`)
|
logger.info('transactionLink', transactionLink)
|
||||||
transactionLink.redeemedAt = receivedCallDate
|
transactionLink.redeemedAt = receivedCallDate
|
||||||
transactionLink.redeemedBy = recipient.id
|
transactionLink.redeemedBy = recipient.id
|
||||||
await queryRunner.manager.update(
|
await queryRunner.manager.update(
|
||||||
@ -271,8 +269,8 @@ export class TransactionResolver {
|
|||||||
sumAmount.mul(-1),
|
sumAmount.mul(-1),
|
||||||
sumHoldAvailableAmount.mul(-1),
|
sumHoldAvailableAmount.mul(-1),
|
||||||
sumHoldAvailableAmount.minus(sumAmount.toString()).mul(-1),
|
sumHoldAvailableAmount.minus(sumAmount.toString()).mul(-1),
|
||||||
firstDate || now,
|
firstDate ?? now,
|
||||||
lastDate || now,
|
lastDate ?? now,
|
||||||
self,
|
self,
|
||||||
(userTransactions.length && userTransactions[0].balance) || new Decimal(0),
|
(userTransactions.length && userTransactions[0].balance) || new Decimal(0),
|
||||||
),
|
),
|
||||||
@ -325,9 +323,7 @@ export class TransactionResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await executeTransaction(amount, memo, senderUser, recipientUser)
|
await executeTransaction(amount, memo, senderUser, recipientUser)
|
||||||
logger.info(
|
logger.info('successful executeTransaction', amount, memo, senderUser, recipientUser)
|
||||||
`successful executeTransaction(amount=${amount}, memo=${memo}, senderUser=${senderUser}, recipientUser=${recipientUser})`,
|
|
||||||
)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import { ContributionLink } from '@model/ContributionLink'
|
|||||||
import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers'
|
import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers'
|
||||||
import { logger, i18n as localization } from '@test/testSetup'
|
import { logger, i18n as localization } from '@test/testSetup'
|
||||||
|
|
||||||
|
import { subscribe } from '@/apis/KlicktippController'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
import {
|
import {
|
||||||
sendAccountActivationEmail,
|
sendAccountActivationEmail,
|
||||||
@ -61,8 +62,6 @@ import { stephenHawking } from '@/seeds/users/stephen-hawking'
|
|||||||
import { printTimeDuration } from '@/util/time'
|
import { printTimeDuration } from '@/util/time'
|
||||||
import { objectValuesToArray } from '@/util/utilities'
|
import { objectValuesToArray } from '@/util/utilities'
|
||||||
|
|
||||||
// import { klicktippSignIn } from '@/apis/KlicktippController'
|
|
||||||
|
|
||||||
jest.mock('@/emails/sendEmailVariants', () => {
|
jest.mock('@/emails/sendEmailVariants', () => {
|
||||||
const originalModule = jest.requireActual('@/emails/sendEmailVariants')
|
const originalModule = jest.requireActual('@/emails/sendEmailVariants')
|
||||||
return {
|
return {
|
||||||
@ -76,15 +75,13 @@ jest.mock('@/emails/sendEmailVariants', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
jest.mock('@/apis/KlicktippController', () => {
|
jest.mock('@/apis/KlicktippController', () => {
|
||||||
return {
|
return {
|
||||||
__esModule: true,
|
__esModule: true,
|
||||||
klicktippSignIn: jest.fn(),
|
subscribe: jest.fn(),
|
||||||
|
getKlickTippUser: jest.fn(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
|
|
||||||
let admin: User
|
let admin: User
|
||||||
let user: User
|
let user: User
|
||||||
@ -556,16 +553,14 @@ describe('UserResolver', () => {
|
|||||||
expect(newUser.password.toString()).toEqual(encryptedPass.toString())
|
expect(newUser.password.toString()).toEqual(encryptedPass.toString())
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
it('calls the klicktipp API', () => {
|
it('calls the klicktipp API', () => {
|
||||||
expect(klicktippSignIn).toBeCalledWith(
|
expect(subscribe).toBeCalledWith(
|
||||||
user[0].email,
|
newUser.emailContact.email,
|
||||||
user[0].language,
|
newUser.language,
|
||||||
user[0].firstName,
|
newUser.firstName,
|
||||||
user[0].lastName,
|
newUser.lastName,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
|
|
||||||
it('returns true', () => {
|
it('returns true', () => {
|
||||||
expect(result).toBeTruthy()
|
expect(result).toBeTruthy()
|
||||||
|
|||||||
@ -35,7 +35,7 @@ import { User } from '@model/User'
|
|||||||
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
|
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
|
||||||
import { UserRepository } from '@repository/User'
|
import { UserRepository } from '@repository/User'
|
||||||
|
|
||||||
import { klicktippSignIn } from '@/apis/KlicktippController'
|
import { subscribe } from '@/apis/KlicktippController'
|
||||||
import { encode } from '@/auth/JWT'
|
import { encode } from '@/auth/JWT'
|
||||||
import { RIGHTS } from '@/auth/RIGHTS'
|
import { RIGHTS } from '@/auth/RIGHTS'
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
@ -95,7 +95,7 @@ const newEmailContact = (email: string, userId: number): DbUserContact => {
|
|||||||
emailContact.emailChecked = false
|
emailContact.emailChecked = false
|
||||||
emailContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
|
emailContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
|
||||||
emailContact.emailVerificationCode = random(64)
|
emailContact.emailVerificationCode = random(64)
|
||||||
logger.debug(`newEmailContact...successful: ${emailContact}`)
|
logger.debug('newEmailContact...successful', emailContact)
|
||||||
return emailContact
|
return emailContact
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ export class UserResolver {
|
|||||||
email = email.trim().toLowerCase()
|
email = email.trim().toLowerCase()
|
||||||
if (await checkEmailExists(email)) {
|
if (await checkEmailExists(email)) {
|
||||||
const foundUser = await findUserByEmail(email)
|
const foundUser = await findUserByEmail(email)
|
||||||
logger.info(`DbUser.findOne(email=${email}) = ${foundUser}`)
|
logger.info('DbUser.findOne', email, foundUser)
|
||||||
|
|
||||||
if (foundUser) {
|
if (foundUser) {
|
||||||
// ATTENTION: this logger-message will be exactly expected during tests, next line
|
// ATTENTION: this logger-message will be exactly expected during tests, next line
|
||||||
@ -276,7 +276,7 @@ export class UserResolver {
|
|||||||
dbUser.firstName = firstName
|
dbUser.firstName = firstName
|
||||||
dbUser.lastName = lastName
|
dbUser.lastName = lastName
|
||||||
dbUser.language = language
|
dbUser.language = language
|
||||||
dbUser.publisherId = publisherId || 0
|
dbUser.publisherId = publisherId ?? 0
|
||||||
dbUser.passwordEncryptionType = PasswordEncryptionType.NO_PASSWORD
|
dbUser.passwordEncryptionType = PasswordEncryptionType.NO_PASSWORD
|
||||||
logger.debug('new dbUser', dbUser)
|
logger.debug('new dbUser', dbUser)
|
||||||
if (redeemCode) {
|
if (redeemCode) {
|
||||||
@ -383,7 +383,7 @@ export class UserResolver {
|
|||||||
throw new LogError('Unable to save email verification code', user.emailContact)
|
throw new LogError('Unable to save email verification code', user.emailContact)
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info(`optInCode for ${email}=${user.emailContact}`)
|
logger.info('optInCode for', email, user.emailContact)
|
||||||
|
|
||||||
void sendResetPasswordEmail({
|
void sendResetPasswordEmail({
|
||||||
firstName: user.firstName,
|
firstName: user.firstName,
|
||||||
@ -469,9 +469,9 @@ export class UserResolver {
|
|||||||
// TODO do we always signUp the user? How to handle things with old users?
|
// TODO do we always signUp the user? How to handle things with old users?
|
||||||
if (userContact.emailOptInTypeId === OptInType.EMAIL_OPT_IN_REGISTER) {
|
if (userContact.emailOptInTypeId === OptInType.EMAIL_OPT_IN_REGISTER) {
|
||||||
try {
|
try {
|
||||||
await klicktippSignIn(userContact.email, user.language, user.firstName, user.lastName)
|
await subscribe(userContact.email, user.language, user.firstName, user.lastName)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`klicktippSignIn(${userContact.email}, ${user.language}, ${user.firstName}, ${user.lastName})`,
|
`subscribe(${userContact.email}, ${user.language}, ${user.firstName}, ${user.lastName})`,
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('Error subscribing to klicktipp', e)
|
logger.error('Error subscribing to klicktipp', e)
|
||||||
@ -487,7 +487,7 @@ export class UserResolver {
|
|||||||
async queryOptIn(@Arg('optIn') optIn: string): Promise<boolean> {
|
async queryOptIn(@Arg('optIn') optIn: string): Promise<boolean> {
|
||||||
logger.info(`queryOptIn(${optIn})...`)
|
logger.info(`queryOptIn(${optIn})...`)
|
||||||
const userContact = await DbUserContact.findOneOrFail({ emailVerificationCode: optIn })
|
const userContact = await DbUserContact.findOneOrFail({ emailVerificationCode: optIn })
|
||||||
logger.debug(`found optInCode=${userContact}`)
|
logger.debug('found optInCode', userContact)
|
||||||
// Code is only valid for `CONFIG.EMAIL_CODE_VALID_TIME` minutes
|
// Code is only valid for `CONFIG.EMAIL_CODE_VALID_TIME` minutes
|
||||||
if (!isEmailVerificationCodeValid(userContact.updatedAt || userContact.createdAt)) {
|
if (!isEmailVerificationCodeValid(userContact.updatedAt || userContact.createdAt)) {
|
||||||
throw new LogError(
|
throw new LogError(
|
||||||
@ -593,7 +593,7 @@ export class UserResolver {
|
|||||||
logger.info(`hasElopage()...`)
|
logger.info(`hasElopage()...`)
|
||||||
const userEntity = getUser(context)
|
const userEntity = getUser(context)
|
||||||
const elopageBuys = hasElopageBuys(userEntity.emailContact.email)
|
const elopageBuys = hasElopageBuys(userEntity.emailContact.email)
|
||||||
logger.debug(`has ElopageBuys = ${elopageBuys}`)
|
logger.debug('has ElopageBuys', elopageBuys)
|
||||||
return elopageBuys
|
return elopageBuys
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,7 +650,7 @@ export class UserResolver {
|
|||||||
return 'user.' + fieldName
|
return 'user.' + fieldName
|
||||||
}),
|
}),
|
||||||
searchText,
|
searchText,
|
||||||
filters || null,
|
filters ?? null,
|
||||||
currentPage,
|
currentPage,
|
||||||
pageSize,
|
pageSize,
|
||||||
)
|
)
|
||||||
@ -716,14 +716,14 @@ export class UserResolver {
|
|||||||
// change isAdmin
|
// change isAdmin
|
||||||
switch (user.isAdmin) {
|
switch (user.isAdmin) {
|
||||||
case null:
|
case null:
|
||||||
if (isAdmin === true) {
|
if (isAdmin) {
|
||||||
user.isAdmin = new Date()
|
user.isAdmin = new Date()
|
||||||
} else {
|
} else {
|
||||||
throw new LogError('User is already an usual user')
|
throw new LogError('User is already an usual user')
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
if (isAdmin === false) {
|
if (!isAdmin) {
|
||||||
user.isAdmin = null
|
user.isAdmin = null
|
||||||
} else {
|
} else {
|
||||||
throw new LogError('User is already admin')
|
throw new LogError('User is already admin')
|
||||||
|
|||||||
@ -29,10 +29,12 @@ export const validateContribution = (
|
|||||||
throw new LogError('No information for available creations for the given date', creationDate)
|
throw new LogError('No information for available creations for the given date', creationDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
if (amount.greaterThan(creations[index].toString())) {
|
if (amount.greaterThan(creations[index].toString())) {
|
||||||
throw new LogError(
|
throw new LogError(
|
||||||
'The amount to be created exceeds the amount still available for this month',
|
'The amount to be created exceeds the amount still available for this month',
|
||||||
amount,
|
amount,
|
||||||
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
creations[index],
|
creations[index],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -151,6 +153,7 @@ export const updateCreations = (
|
|||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
throw new LogError('You cannot create GDD for a month older than the last three months')
|
throw new LogError('You cannot create GDD for a month older than the last three months')
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
creations[index] = creations[index].plus(contribution.amount.toString())
|
creations[index] = creations[index].plus(contribution.amount.toString())
|
||||||
return creations
|
return creations
|
||||||
}
|
}
|
||||||
@ -169,6 +172,7 @@ export const getOpenCreations = async (
|
|||||||
return {
|
return {
|
||||||
month: date.getMonth(),
|
month: date.getMonth(),
|
||||||
year: date.getFullYear(),
|
year: date.getFullYear(),
|
||||||
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
amount: creations[index],
|
amount: creations[index],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const findContributions = async (
|
|||||||
}
|
}
|
||||||
return DbContribution.findAndCount({
|
return DbContribution.findAndCount({
|
||||||
where: {
|
where: {
|
||||||
...(statusFilter && statusFilter.length && { contributionStatus: In(statusFilter) }),
|
...(statusFilter?.length && { contributionStatus: In(statusFilter) }),
|
||||||
...(userId && { userId }),
|
...(userId && { userId }),
|
||||||
},
|
},
|
||||||
withDeleted,
|
withDeleted,
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export async function transactionLinkList(
|
|||||||
filters: TransactionLinkFilters | null,
|
filters: TransactionLinkFilters | null,
|
||||||
user: DbUser,
|
user: DbUser,
|
||||||
): Promise<TransactionLinkResult> {
|
): Promise<TransactionLinkResult> {
|
||||||
const { withDeleted, withExpired, withRedeemed } = filters || {
|
const { withDeleted, withExpired, withRedeemed } = filters ?? {
|
||||||
withDeleted: false,
|
withDeleted: false,
|
||||||
withExpired: false,
|
withExpired: false,
|
||||||
withRedeemed: false,
|
withRedeemed: false,
|
||||||
|
|||||||
@ -13,7 +13,7 @@ async function main() {
|
|||||||
console.log(`GraphIQL available at http://localhost:${CONFIG.PORT}`)
|
console.log(`GraphIQL available at http://localhost:${CONFIG.PORT}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
void startValidateCommunities(Number(CONFIG.FEDERATION_VALIDATE_COMMUNITY_TIMER))
|
startValidateCommunities(Number(CONFIG.FEDERATION_VALIDATE_COMMUNITY_TIMER))
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch((e) => {
|
main().catch((e) => {
|
||||||
|
|||||||
@ -10,19 +10,6 @@ import { KlickTipp } from '@model/KlickTipp'
|
|||||||
import { getKlickTippUser } from '@/apis/KlicktippController'
|
import { getKlickTippUser } from '@/apis/KlicktippController'
|
||||||
import { klickTippLogger as logger } from '@/server/logger'
|
import { klickTippLogger as logger } from '@/server/logger'
|
||||||
|
|
||||||
// export const klicktippRegistrationMiddleware: MiddlewareFn = async (
|
|
||||||
// // Only for demo
|
|
||||||
// /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
|
||||||
// { root, args, context, info },
|
|
||||||
// next,
|
|
||||||
// ) => {
|
|
||||||
// // Do Something here before resolver is called
|
|
||||||
// const result = await next()
|
|
||||||
// // Do Something here after resolver is completed
|
|
||||||
// await klicktippSignIn(result.email, result.language, result.firstName, result.lastName)
|
|
||||||
// return result
|
|
||||||
// }
|
|
||||||
|
|
||||||
export const klicktippNewsletterStateMiddleware: MiddlewareFn = async (
|
export const klicktippNewsletterStateMiddleware: MiddlewareFn = async (
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
||||||
{ root, args, context, info },
|
{ root, args, context, info },
|
||||||
|
|||||||
@ -31,8 +31,8 @@ const context = {
|
|||||||
|
|
||||||
export const cleanDB = async () => {
|
export const cleanDB = async () => {
|
||||||
// this only works as long we do not have foreign key constraints
|
// this only works as long we do not have foreign key constraints
|
||||||
for (let i = 0; i < entities.length; i++) {
|
for (const entity of entities) {
|
||||||
await resetEntity(entities[i])
|
await resetEntity(entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +54,8 @@ const run = async () => {
|
|||||||
logger.info('##seed## clean database successful...')
|
logger.info('##seed## clean database successful...')
|
||||||
|
|
||||||
// seed the standard users
|
// seed the standard users
|
||||||
for (let i = 0; i < users.length; i++) {
|
for (const user of users) {
|
||||||
const dbUser = await userFactory(seedClient, users[i])
|
await userFactory(seedClient, user)
|
||||||
logger.info(`##seed## seed standard users[ ${i} ]= ${JSON.stringify(dbUser, null, 2)}`)
|
|
||||||
}
|
}
|
||||||
logger.info('##seed## seeding all standard users successful...')
|
logger.info('##seed## seeding all standard users successful...')
|
||||||
|
|
||||||
@ -73,20 +72,20 @@ const run = async () => {
|
|||||||
logger.info('##seed## seeding all random users successful...')
|
logger.info('##seed## seeding all random users successful...')
|
||||||
|
|
||||||
// create GDD
|
// create GDD
|
||||||
for (let i = 0; i < creations.length; i++) {
|
for (const creation of creations) {
|
||||||
await creationFactory(seedClient, creations[i])
|
await creationFactory(seedClient, creation)
|
||||||
}
|
}
|
||||||
logger.info('##seed## seeding all creations successful...')
|
logger.info('##seed## seeding all creations successful...')
|
||||||
|
|
||||||
// create Transaction Links
|
// create Transaction Links
|
||||||
for (let i = 0; i < transactionLinks.length; i++) {
|
for (const transactionLink of transactionLinks) {
|
||||||
await transactionLinkFactory(seedClient, transactionLinks[i])
|
await transactionLinkFactory(seedClient, transactionLink)
|
||||||
}
|
}
|
||||||
logger.info('##seed## seeding all transactionLinks successful...')
|
logger.info('##seed## seeding all transactionLinks successful...')
|
||||||
|
|
||||||
// create Contribution Links
|
// create Contribution Links
|
||||||
for (let i = 0; i < contributionLinks.length; i++) {
|
for (const contributionLink of contributionLinks) {
|
||||||
await contributionLinkFactory(seedClient, contributionLinks[i])
|
await contributionLinkFactory(seedClient, contributionLink)
|
||||||
}
|
}
|
||||||
logger.info('##seed## seeding all contributionLinks successful...')
|
logger.info('##seed## seeding all contributionLinks successful...')
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,11 @@ import { plugins } from './plugins'
|
|||||||
// TODO implement
|
// TODO implement
|
||||||
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
|
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
|
||||||
|
|
||||||
type ServerDef = { apollo: ApolloServer; app: Express; con: Connection }
|
interface ServerDef {
|
||||||
|
apollo: ApolloServer
|
||||||
|
app: Express
|
||||||
|
con: Connection
|
||||||
|
}
|
||||||
|
|
||||||
export const createServer = async (
|
export const createServer = async (
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@ -34,7 +38,7 @@ export const createServer = async (
|
|||||||
|
|
||||||
// open mysql connection
|
// open mysql connection
|
||||||
const con = await connection()
|
const con = await connection()
|
||||||
if (!con || !con.isConnected) {
|
if (!con?.isConnected) {
|
||||||
logger.fatal(`Couldn't open connection to database!`)
|
logger.fatal(`Couldn't open connection to database!`)
|
||||||
throw new Error(`Fatal: Couldn't open connection to database`)
|
throw new Error(`Fatal: Couldn't open connection to database`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { configure, getLogger } from 'log4js'
|
|||||||
|
|
||||||
import { CONFIG } from '@/config'
|
import { CONFIG } from '@/config'
|
||||||
|
|
||||||
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||||
const options = JSON.parse(readFileSync(CONFIG.LOG4JS_CONFIG, 'utf-8'))
|
const options = JSON.parse(readFileSync(CONFIG.LOG4JS_CONFIG, 'utf-8'))
|
||||||
|
|
||||||
options.categories.backend.level = CONFIG.LOG_LEVEL
|
options.categories.backend.level = CONFIG.LOG_LEVEL
|
||||||
|
|||||||
@ -12,7 +12,7 @@ const setHeadersPlugin = {
|
|||||||
return {
|
return {
|
||||||
willSendResponse(requestContext: any) {
|
willSendResponse(requestContext: any) {
|
||||||
const { setHeaders = [] } = requestContext.context
|
const { setHeaders = [] } = requestContext.context
|
||||||
setHeaders.forEach(({ key, value }: { [key: string]: string }) => {
|
setHeaders.forEach(({ key, value }: Record<string, string>) => {
|
||||||
if (requestContext.response.http.headers.get(key)) {
|
if (requestContext.response.http.headers.get(key)) {
|
||||||
requestContext.response.http.headers.set(key, value)
|
requestContext.response.http.headers.set(key, value)
|
||||||
} else {
|
} else {
|
||||||
@ -27,8 +27,8 @@ const setHeadersPlugin = {
|
|||||||
|
|
||||||
const filterVariables = (variables: any) => {
|
const filterVariables = (variables: any) => {
|
||||||
const vars = clonedeep(variables)
|
const vars = clonedeep(variables)
|
||||||
if (vars && vars.password) vars.password = '***'
|
if (vars?.password) vars.password = '***'
|
||||||
if (vars && vars.passwordNew) vars.passwordNew = '***'
|
if (vars?.passwordNew) vars.passwordNew = '***'
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,10 +14,10 @@ const getDBVersion = async (): Promise<string | null> => {
|
|||||||
|
|
||||||
const checkDBVersion = async (DB_VERSION: string): Promise<boolean> => {
|
const checkDBVersion = async (DB_VERSION: string): Promise<boolean> => {
|
||||||
const dbVersion = await getDBVersion()
|
const dbVersion = await getDBVersion()
|
||||||
if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) {
|
if (!dbVersion?.includes(DB_VERSION)) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Wrong database version detected - the backend requires '${DB_VERSION}' but found '${
|
`Wrong database version detected - the backend requires '${DB_VERSION}' but found '${
|
||||||
dbVersion || 'None'
|
dbVersion ?? 'None'
|
||||||
}`,
|
}`,
|
||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -11,8 +11,7 @@ export async function retrieveNotRegisteredEmails(): Promise<string[]> {
|
|||||||
}
|
}
|
||||||
const users = await User.find({ relations: ['emailContact'] })
|
const users = await User.find({ relations: ['emailContact'] })
|
||||||
const notRegisteredUser = []
|
const notRegisteredUser = []
|
||||||
for (let i = 0; i < users.length; i++) {
|
for (const user of users) {
|
||||||
const user = users[i]
|
|
||||||
try {
|
try {
|
||||||
await getKlickTippUser(user.emailContact.email)
|
await getKlickTippUser(user.emailContact.email)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { Decimal } from 'decimal.js-light'
|
import { Decimal } from 'decimal.js-light'
|
||||||
import i18n from 'i18n'
|
import i18n from 'i18n'
|
||||||
|
|
||||||
export const objectValuesToArray = (obj: { [x: string]: string }): Array<string> => {
|
export const objectValuesToArray = (obj: Record<string, string>): string[] =>
|
||||||
return Object.keys(obj).map(function (key) {
|
// eslint-disable-next-line security/detect-object-injection
|
||||||
return obj[key]
|
Object.keys(obj).map((key) => obj[key])
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const decimalSeparatorByLanguage = (a: Decimal, language: string): string => {
|
export const decimalSeparatorByLanguage = (a: Decimal, language: string): string => {
|
||||||
const rememberLocaleToRestore = i18n.getLocale()
|
const rememberLocaleToRestore = i18n.getLocale()
|
||||||
|
|||||||
@ -115,6 +115,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
|||||||
) {
|
) {
|
||||||
const email = loginElopageBuy.payerEmail
|
const email = loginElopageBuy.payerEmail
|
||||||
|
|
||||||
|
// eslint-disable-next-line security/detect-unsafe-regex
|
||||||
const VALIDATE_EMAIL = /^[a-zA-Z0-9.!#$%&?*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
|
const VALIDATE_EMAIL = /^[a-zA-Z0-9.!#$%&?*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
|
||||||
const VALIDATE_NAME = /^<>&;]{2,}$/
|
const VALIDATE_NAME = /^<>&;]{2,}$/
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
|||||||
email,
|
email,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
publisherId: loginElopageBuy.publisherId || 0, // This seemed to be the default value if not set
|
publisherId: loginElopageBuy.publisherId ?? 0, // This seemed to be the default value if not set
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
|||||||
@ -22,8 +22,8 @@ const context = {
|
|||||||
|
|
||||||
export const cleanDB = async () => {
|
export const cleanDB = async () => {
|
||||||
// this only works as lond we do not have foreign key constraints
|
// this only works as lond we do not have foreign key constraints
|
||||||
for (let i = 0; i < entities.length; i++) {
|
for (const entity of entities) {
|
||||||
await resetEntity(entities[i])
|
await resetEntity(entity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -382,6 +382,14 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@cspotcode/source-map-consumer" "0.8.0"
|
"@cspotcode/source-map-consumer" "0.8.0"
|
||||||
|
|
||||||
|
"@eslint-community/eslint-plugin-eslint-comments@^3.2.1":
|
||||||
|
version "3.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.1.tgz#3c65061e27f155eae3744c3b30c5a8253a959040"
|
||||||
|
integrity sha512-/HZbjIGaVO2zLlWX3gRgiHmKRVvvqrC0zVu3eXnIj1ORxoyfGSj50l0PfDfqihyZAqrDYzSMdJesXzFjvAoiLQ==
|
||||||
|
dependencies:
|
||||||
|
escape-string-regexp "^1.0.5"
|
||||||
|
ignore "^5.2.4"
|
||||||
|
|
||||||
"@eslint-community/eslint-utils@^4.2.0":
|
"@eslint-community/eslint-utils@^4.2.0":
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz#a831e6e468b4b2b5ae42bf658bea015bf10bc518"
|
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz#a831e6e468b4b2b5ae42bf658bea015bf10bc518"
|
||||||
@ -3005,6 +3013,13 @@ eslint-plugin-promise@^6.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816"
|
||||||
integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==
|
integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==
|
||||||
|
|
||||||
|
eslint-plugin-security@^1.7.1:
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-plugin-security/-/eslint-plugin-security-1.7.1.tgz#0e9c4a471f6e4d3ca16413c7a4a51f3966ba16e4"
|
||||||
|
integrity sha512-sMStceig8AFglhhT2LqlU5r+/fn9OwsA72O5bBuQVTssPCdQAOQzL+oMn/ZcpeUY6KcNfLJArgcrsSULNjYYdQ==
|
||||||
|
dependencies:
|
||||||
|
safe-regex "^2.1.1"
|
||||||
|
|
||||||
eslint-plugin-type-graphql@^1.0.0:
|
eslint-plugin-type-graphql@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-type-graphql/-/eslint-plugin-type-graphql-1.0.0.tgz#d348560ed628d6ca1dfcea35a02891432daafe6b"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-type-graphql/-/eslint-plugin-type-graphql-1.0.0.tgz#d348560ed628d6ca1dfcea35a02891432daafe6b"
|
||||||
@ -3649,7 +3664,7 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
|||||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||||
|
|
||||||
"gradido-database@file:../database":
|
"gradido-database@file:../database":
|
||||||
version "1.19.1"
|
version "1.20.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/uuid" "^8.3.4"
|
"@types/uuid" "^8.3.4"
|
||||||
cross-env "^7.0.3"
|
cross-env "^7.0.3"
|
||||||
@ -3977,7 +3992,7 @@ ignore@^5.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
|
||||||
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
|
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
|
||||||
|
|
||||||
ignore@^5.2.0:
|
ignore@^5.2.0, ignore@^5.2.4:
|
||||||
version "5.2.4"
|
version "5.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
|
||||||
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
|
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
|
||||||
@ -6140,6 +6155,11 @@ reflect-metadata@^0.1.13:
|
|||||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
|
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
|
||||||
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
|
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
|
||||||
|
|
||||||
|
regexp-tree@~0.1.1:
|
||||||
|
version "0.1.27"
|
||||||
|
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd"
|
||||||
|
integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==
|
||||||
|
|
||||||
regexp.prototype.flags@^1.4.3:
|
regexp.prototype.flags@^1.4.3:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
|
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
|
||||||
@ -6279,6 +6299,13 @@ safe-regex-test@^1.0.0:
|
|||||||
get-intrinsic "^1.1.3"
|
get-intrinsic "^1.1.3"
|
||||||
is-regex "^1.1.4"
|
is-regex "^1.1.4"
|
||||||
|
|
||||||
|
safe-regex@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2"
|
||||||
|
integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==
|
||||||
|
dependencies:
|
||||||
|
regexp-tree "~0.1.1"
|
||||||
|
|
||||||
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
|
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
|
|||||||
@ -117,7 +117,7 @@ server {
|
|||||||
|
|
||||||
# TODO this could be a performance optimization
|
# TODO this could be a performance optimization
|
||||||
#location /vue {
|
#location /vue {
|
||||||
# alias /var/www/html/gradido/frontend/dist;
|
# alias /var/www/html/gradido/frontend/build;
|
||||||
# index index.html;
|
# index index.html;
|
||||||
#
|
#
|
||||||
# location ~* \.(png)$ {
|
# location ~* \.(png)$ {
|
||||||
|
|||||||
@ -103,7 +103,7 @@ server {
|
|||||||
|
|
||||||
# TODO this could be a performance optimization
|
# TODO this could be a performance optimization
|
||||||
#location /vue {
|
#location /vue {
|
||||||
# alias /var/www/html/gradido/frontend/dist;
|
# alias /var/www/html/gradido/frontend/build;
|
||||||
# index index.html;
|
# index index.html;
|
||||||
#
|
#
|
||||||
# location ~* \.(png)$ {
|
# location ~* \.(png)$ {
|
||||||
|
|||||||
@ -15,6 +15,6 @@ export NVM_DIR="/root/.nvm"
|
|||||||
$NPM_BIN install
|
$NPM_BIN install
|
||||||
$NPM_BIN run build
|
$NPM_BIN run build
|
||||||
# prezip for faster deliver throw nginx
|
# prezip for faster deliver throw nginx
|
||||||
cd dist
|
cd build
|
||||||
find . -type f -name "*.css" -exec gzip -9 -k {} \;
|
find . -type f -name "*.css" -exec gzip -9 -k {} \;
|
||||||
find . -type f -name "*.js" -exec gzip -9 -k {} \;
|
find . -type f -name "*.js" -exec gzip -9 -k {} \;
|
||||||
|
|||||||
@ -130,6 +130,15 @@ rm -Rf $PROJECT_ROOT/admin/node_modules
|
|||||||
rm -Rf $PROJECT_ROOT/dht-node/node_modules
|
rm -Rf $PROJECT_ROOT/dht-node/node_modules
|
||||||
rm -Rf $PROJECT_ROOT/federation/node_modules
|
rm -Rf $PROJECT_ROOT/federation/node_modules
|
||||||
|
|
||||||
|
# Remove build folders
|
||||||
|
# we had problems with corrupted incremtal builds
|
||||||
|
rm -Rf $PROJECT_ROOT/database/build
|
||||||
|
rm -Rf $PROJECT_ROOT/backend/build
|
||||||
|
rm -Rf $PROJECT_ROOT/frontend/build
|
||||||
|
rm -Rf $PROJECT_ROOT/admin/build
|
||||||
|
rm -Rf $PROJECT_ROOT/dht-node/build
|
||||||
|
rm -Rf $PROJECT_ROOT/federation/build
|
||||||
|
|
||||||
# Regenerate .env files
|
# Regenerate .env files
|
||||||
cp -f $PROJECT_ROOT/database/.env $PROJECT_ROOT/database/.env.bak
|
cp -f $PROJECT_ROOT/database/.env $PROJECT_ROOT/database/.env.bak
|
||||||
cp -f $PROJECT_ROOT/backend/.env $PROJECT_ROOT/backend/.env.bak
|
cp -f $PROJECT_ROOT/backend/.env $PROJECT_ROOT/backend/.env.bak
|
||||||
|
|||||||
@ -35,6 +35,6 @@ Cypress.Commands.add('login', (email, password) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cy.visit('/')
|
cy.visit('/')
|
||||||
window.localStorage.setItem('vuex', JSON.stringify(vuexToken))
|
window.localStorage.setItem('gradido-frontend', JSON.stringify(vuexToken))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
build/
|
||||||
coverage/
|
coverage/
|
||||||
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@ -1,6 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
build/
|
||||||
.cache/
|
.cache/
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
|
|||||||
@ -84,7 +84,7 @@ CMD /bin/sh -c "yarn run dev"
|
|||||||
FROM base as production
|
FROM base as production
|
||||||
|
|
||||||
# Copy "binary"-files from build image
|
# Copy "binary"-files from build image
|
||||||
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
|
COPY --from=build ${DOCKER_WORKDIR}/build ./build
|
||||||
# We also copy the node_modules express and serve-static for the run script
|
# We also copy the node_modules express and serve-static for the run script
|
||||||
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||||
# Copy static files
|
# Copy static files
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
"serve": "vue-cli-service serve --open",
|
"serve": "vue-cli-service serve --open",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"dev": "yarn run serve",
|
"dev": "yarn run serve",
|
||||||
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
|
"analyse-bundle": "yarn build && webpack-bundle-analyzer build/webpack.stats.json",
|
||||||
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
|
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
|
||||||
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
|
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
|
||||||
"test": "cross-env TZ=UTC jest",
|
"test": "cross-env TZ=UTC jest",
|
||||||
|
|||||||
@ -9,10 +9,10 @@ const port = process.env.PORT || 3000
|
|||||||
// Express Server
|
// Express Server
|
||||||
const app = express()
|
const app = express()
|
||||||
// Serve files
|
// Serve files
|
||||||
app.use(express.static(path.join(__dirname, '../dist')))
|
app.use(express.static(path.join(__dirname, '../build')))
|
||||||
// Default to index.html
|
// Default to index.html
|
||||||
app.get('*', (req, res) => {
|
app.get('*', (req, res) => {
|
||||||
res.sendFile(path.join(__dirname, '../dist/index.html'))
|
res.sendFile(path.join(__dirname, '../build/index.html'))
|
||||||
})
|
})
|
||||||
|
|
||||||
app.listen(port, hostname, () => {
|
app.listen(port, hostname, () => {
|
||||||
|
|||||||
@ -91,6 +91,7 @@ try {
|
|||||||
store = new Vuex.Store({
|
store = new Vuex.Store({
|
||||||
plugins: [
|
plugins: [
|
||||||
createPersistedState({
|
createPersistedState({
|
||||||
|
key: 'gradido-frontend',
|
||||||
storage: window.localStorage,
|
storage: window.localStorage,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -64,5 +64,5 @@ module.exports = {
|
|||||||
// Enable CSS source maps.
|
// Enable CSS source maps.
|
||||||
sourceMap: CONFIG.NODE_ENV !== 'production',
|
sourceMap: CONFIG.NODE_ENV !== 'production',
|
||||||
},
|
},
|
||||||
outputDir: path.resolve(__dirname, './dist'),
|
outputDir: path.resolve(__dirname, './build'),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ server {
|
|||||||
|
|
||||||
# TODO this could be a performance optimization
|
# TODO this could be a performance optimization
|
||||||
#location /vue {
|
#location /vue {
|
||||||
# alias /var/www/html/gradido/frontend/dist;
|
# alias /var/www/html/gradido/frontend/build;
|
||||||
# index index.html;
|
# index index.html;
|
||||||
#
|
#
|
||||||
# location ~* \.(png)$ {
|
# location ~* \.(png)$ {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user