diff --git a/federation/src/config/index.ts b/federation/src/config/index.ts index 2fe928935..5c13524d6 100644 --- a/federation/src/config/index.ts +++ b/federation/src/config/index.ts @@ -1,6 +1,6 @@ // ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) -import dotenv from 'dotenv' -dotenv.config() +import dotenv from "dotenv"; +dotenv.config(); /* import Decimal from 'decimal.js-light' @@ -11,34 +11,35 @@ Decimal.set({ */ const constants = { - DB_VERSION: '0058-add_communities_table', + DB_VERSION: "0059-add_hide_amount_to_users", // 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 - LOG_LEVEL: process.env.LOG_LEVEL || 'info', + LOG_LEVEL: process.env.LOG_LEVEL || "info", CONFIG_VERSION: { - DEFAULT: 'DEFAULT', - EXPECTED: 'v1.2023-01-09', - CURRENT: '', + DEFAULT: "DEFAULT", + EXPECTED: "v1.2023-01-09", + CURRENT: "", }, -} +}; const server = { PORT: process.env.PORT || 5000, // JWT_SECRET: process.env.JWT_SECRET || 'secret123', // 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', - PRODUCTION: process.env.NODE_ENV === 'production' || false, -} + PRODUCTION: process.env.NODE_ENV === "production" || false, +}; 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_USER: process.env.DB_USER || 'root', - DB_PASSWORD: process.env.DB_PASSWORD || '', - DB_DATABASE: process.env.DB_DATABASE || 'gradido_community', - TYPEORM_LOGGING_RELATIVE_PATH: process.env.TYPEORM_LOGGING_RELATIVE_PATH || 'typeorm.backend.log', -} + DB_USER: process.env.DB_USER || "root", + DB_PASSWORD: process.env.DB_PASSWORD || "", + DB_DATABASE: process.env.DB_DATABASE || "gradido_community", + TYPEORM_LOGGING_RELATIVE_PATH: + process.env.TYPEORM_LOGGING_RELATIVE_PATH || "typeorm.backend.log", +}; /* const community = { COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', @@ -52,40 +53,42 @@ const community = { } */ // const eventProtocol = { - // global switch to enable writing of EventProtocol-Entries - // EVENT_PROTOCOL_DISABLED: process.env.EVENT_PROTOCOL_DISABLED === 'true' || false, +// global switch to enable writing of EventProtocol-Entries +// EVENT_PROTOCOL_DISABLED: process.env.EVENT_PROTOCOL_DISABLED === 'true' || false, // } // This is needed by graphql-directive-auth // process.env.APP_SECRET = server.JWT_SECRET // 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 ( - ![constants.CONFIG_VERSION.EXPECTED, constants.CONFIG_VERSION.DEFAULT].includes( - constants.CONFIG_VERSION.CURRENT, - ) + ![ + constants.CONFIG_VERSION.EXPECTED, + constants.CONFIG_VERSION.DEFAULT, + ].includes(constants.CONFIG_VERSION.CURRENT) ) { throw new Error( - `Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"`, - ) + `Fatal: Config Version incorrect - expected "${constants.CONFIG_VERSION.EXPECTED}" or "${constants.CONFIG_VERSION.DEFAULT}", but found "${constants.CONFIG_VERSION.CURRENT}"` + ); } const federation = { // FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || null, // FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED || null, FEDERATION_PORT: process.env.FEDERATION_PORT || 5000, - FEDERATION_API: process.env.FEDERATION_API || '1_0', + FEDERATION_API: process.env.FEDERATION_API || "1_0", FEDERATION_COMMUNITY_URL: process.env.FEDERATION_COMMUNITY_URL || null, -} +}; const CONFIG = { ...constants, ...server, ...database, - //...community, - //...eventProtocol, + // ...community, + // ...eventProtocol, ...federation, -} +}; -export default CONFIG +export default CONFIG; diff --git a/federation/src/graphql/api/1_0/resolver/TestResolver.ts b/federation/src/graphql/api/1_0/resolver/TestResolver.ts index ed60d39c9..8e85de35d 100644 --- a/federation/src/graphql/api/1_0/resolver/TestResolver.ts +++ b/federation/src/graphql/api/1_0/resolver/TestResolver.ts @@ -1,22 +1,21 @@ -import { Field, ObjectType, Query, Resolver } from 'type-graphql' -import { federationLogger as logger } from '@/server/logger' +import { Field, ObjectType, Query, Resolver } from "type-graphql"; +import { federationLogger as logger } from "@/server/logger"; @ObjectType() class GetTestApiResult { constructor(apiVersion: string) { - this.api = `${apiVersion}` + this.api = `${apiVersion}`; } @Field(() => String) - api: string + api: string; } @Resolver() -export class TestResolver { +export class TestResolver { @Query(() => GetTestApiResult) async test(): Promise { - logger.info(`test api 1_0`) - return new GetTestApiResult("1_0") + logger.info(`test api 1_0`); + return new GetTestApiResult("1_0"); } } - diff --git a/federation/src/graphql/api/schema.ts b/federation/src/graphql/api/schema.ts index 1aea4de8b..10598d681 100644 --- a/federation/src/graphql/api/schema.ts +++ b/federation/src/graphql/api/schema.ts @@ -1,9 +1,12 @@ -import path from 'path' +import path from "path"; // config -import CONFIG from '../../config' -import { federationLogger as logger } from '@/server/logger' +import CONFIG from "../../config"; +import { federationLogger as logger } from "@/server/logger"; -export const getApiResolvers = () => { - logger.info(`getApiResolvers...${CONFIG.FEDERATION_API}`) - return path.join(__dirname, `./${CONFIG.FEDERATION_API}/resolver/*Resolver.{ts,js}`) -} +export const getApiResolvers = (): string => { + logger.info(`getApiResolvers...${CONFIG.FEDERATION_API}`); + return path.join( + __dirname, + `./${CONFIG.FEDERATION_API}/resolver/*Resolver.{ts,js}` + ); +}; diff --git a/federation/src/graphql/schema.ts b/federation/src/graphql/schema.ts index 92977882b..c46e8fdd5 100644 --- a/federation/src/graphql/schema.ts +++ b/federation/src/graphql/schema.ts @@ -1,17 +1,17 @@ -import { GraphQLSchema } from 'graphql' -import { buildSchema } from 'type-graphql' +import { GraphQLSchema } from "graphql"; +import { buildSchema } from "type-graphql"; // import isAuthorized from './directive/isAuthorized' -import DecimalScalar from './scalar/Decimal' -import Decimal from 'decimal.js-light' -import { getApiResolvers } from './api/schema' +import DecimalScalar from "./scalar/Decimal"; +import Decimal from "decimal.js-light"; +import { getApiResolvers } from "./api/schema"; const schema = async (): Promise => { return await buildSchema({ resolvers: [getApiResolvers()], // authChecker: isAuthorized, scalarsMap: [{ type: Decimal, scalar: DecimalScalar }], - }) -} + }); +}; -export default schema +export default schema; diff --git a/federation/src/index.ts b/federation/src/index.ts index 32d191990..b73b34d04 100644 --- a/federation/src/index.ts +++ b/federation/src/index.ts @@ -1,28 +1,33 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import createServer from './server/createServer' +import createServer from "./server/createServer"; // config -import CONFIG from './config' +import CONFIG from "./config"; async function main() { // eslint-disable-next-line no-console - console.log(`FEDERATION_PORT=${CONFIG.FEDERATION_PORT}`) - console.log(`FEDERATION_API=${CONFIG.FEDERATION_API}`) - const { app } = await createServer() - + console.log(`FEDERATION_PORT=${CONFIG.FEDERATION_PORT}`); + // eslint-disable-next-line no-console + console.log(`FEDERATION_API=${CONFIG.FEDERATION_API}`); + const { app } = await createServer(); + app.listen(CONFIG.FEDERATION_PORT, () => { // eslint-disable-next-line no-console - console.log(`Server is running at http://localhost:${CONFIG.FEDERATION_PORT}`) + console.log( + `Server is running at http://localhost:${CONFIG.FEDERATION_PORT}` + ); if (CONFIG.GRAPHIQL) { // eslint-disable-next-line no-console - console.log(`GraphIQL available at http://localhost:${CONFIG.FEDERATION_PORT}`) + console.log( + `GraphIQL available at http://localhost:${CONFIG.FEDERATION_PORT}` + ); } - }) + }); } main().catch((e) => { // eslint-disable-next-line no-console - console.error(e) - process.exit(1) -}) + console.error(e); + process.exit(1); +}); diff --git a/federation/src/server/cors.ts b/federation/src/server/cors.ts index e76ed1591..3e1fdc4c4 100644 --- a/federation/src/server/cors.ts +++ b/federation/src/server/cors.ts @@ -1,8 +1,8 @@ -import cors from 'cors' +import cors from "cors"; const corsOptions = { - origin: '*', - exposedHeaders: ['token'], -} + origin: "*", + exposedHeaders: ["token"], +}; -export default cors(corsOptions) +export default cors(corsOptions); diff --git a/federation/src/server/createServer.ts b/federation/src/server/createServer.ts index a47b6da7f..c270dfeba 100644 --- a/federation/src/server/createServer.ts +++ b/federation/src/server/createServer.ts @@ -1,29 +1,29 @@ -import 'reflect-metadata' +import "reflect-metadata"; -import { ApolloServer } from 'apollo-server-express' -import express, { Express } from 'express' +import { ApolloServer } from "apollo-server-express"; +import express, { Express } from "express"; // database -import connection from '@/typeorm/connection' -import { checkDBVersion } from '@/typeorm/DBVersion' +import connection from "@/typeorm/connection"; +import { checkDBVersion } from "@/typeorm/DBVersion"; // server -import cors from './cors' +import cors from "./cors"; // import serverContext from './context' -import plugins from './plugins' +import plugins from "./plugins"; // config -import CONFIG from '@/config' +import CONFIG from "@/config"; // graphql -import schema from '@/graphql/schema' +import schema from "@/graphql/schema"; // webhooks // import { elopageWebhook } from '@/webhook/elopage' -import { Connection } from '@dbTools/typeorm' +import { Connection } from "@dbTools/typeorm"; -import { apolloLogger } from './logger' -import { Logger } from 'log4js' +import { apolloLogger } from "./logger"; +import { Logger } from "log4js"; // i18n // import { i18n } from './localization' @@ -31,41 +31,41 @@ import { Logger } from 'log4js' // TODO implement // import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity"; -type ServerDef = { apollo: ApolloServer; app: Express; con: Connection } +type ServerDef = { apollo: ApolloServer; app: Express; con: Connection }; const createServer = async ( // eslint-disable-next-line @typescript-eslint/no-explicit-any // context: any = serverContext, - logger: Logger = apolloLogger, + logger: Logger = apolloLogger // localization: i18n.I18n = i18n, ): Promise => { - logger.addContext('user', 'unknown') - logger.debug('createServer...') + logger.addContext("user", "unknown"); + logger.debug("createServer..."); // open mysql connection - const con = await connection() + const con = await connection(); if (!con || !con.isConnected) { - logger.fatal(`Couldn't open connection to database!`) - throw new Error(`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`); } // check for correct database version - const dbVersion = await checkDBVersion(CONFIG.DB_VERSION) + const dbVersion = await checkDBVersion(CONFIG.DB_VERSION); if (!dbVersion) { - logger.fatal('Fatal: Database Version incorrect') - throw new Error('Fatal: Database Version incorrect') + logger.fatal("Fatal: Database Version incorrect"); + throw new Error("Fatal: Database Version incorrect"); } // Express Server - const app = express() + const app = express(); // cors - app.use(cors) + app.use(cors); // bodyparser json - app.use(express.json()) + app.use(express.json()); // bodyparser urlencoded for elopage - app.use(express.urlencoded({ extended: true })) + app.use(express.urlencoded({ extended: true })); // i18n // app.use(localization.init) @@ -81,11 +81,11 @@ const createServer = async ( // context, plugins, logger, - }) - apollo.applyMiddleware({ app, path: '/' }) - logger.debug('createServer...successful') + }); + apollo.applyMiddleware({ app, path: "/" }); + logger.debug("createServer...successful"); - return { apollo, app, con } -} + return { apollo, app, con }; +}; -export default createServer +export default createServer; diff --git a/federation/src/server/logger.ts b/federation/src/server/logger.ts index d5f4f6b44..6f780fbbe 100644 --- a/federation/src/server/logger.ts +++ b/federation/src/server/logger.ts @@ -1,29 +1,43 @@ -import log4js from 'log4js' -import CONFIG from '@/config' +import log4js from "log4js"; +import CONFIG from "@/config"; -import { readFileSync } from 'fs' +import { readFileSync } from "fs"; -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.apollo.level = CONFIG.LOG_LEVEL -let filename: string = options.appenders.federation.filename -options.appenders.federation.filename = filename.replace('%v', CONFIG.FEDERATION_API).replace('%p', CONFIG.FEDERATION_PORT.toString()) -filename = options.appenders.access.filename -options.appenders.access.filename = filename.replace('%p', CONFIG.FEDERATION_PORT.toString()) -filename = options.appenders.apollo.filename -options.appenders.apollo.filename = filename.replace('%p', CONFIG.FEDERATION_PORT.toString()) -filename = options.appenders.backend.filename -options.appenders.backend.filename = filename.replace('%p', CONFIG.FEDERATION_PORT.toString()) -filename = options.appenders.errorFile.filename -options.appenders.errorFile.filename = filename.replace('%p', CONFIG.FEDERATION_PORT.toString()) +options.categories.backend.level = CONFIG.LOG_LEVEL; +options.categories.apollo.level = CONFIG.LOG_LEVEL; +let filename: string = options.appenders.federation.filename; +options.appenders.federation.filename = filename + .replace("%v", CONFIG.FEDERATION_API) + .replace("%p", CONFIG.FEDERATION_PORT.toString()); +filename = options.appenders.access.filename; +options.appenders.access.filename = filename.replace( + "%p", + CONFIG.FEDERATION_PORT.toString() +); +filename = options.appenders.apollo.filename; +options.appenders.apollo.filename = filename.replace( + "%p", + CONFIG.FEDERATION_PORT.toString() +); +filename = options.appenders.backend.filename; +options.appenders.backend.filename = filename.replace( + "%p", + CONFIG.FEDERATION_PORT.toString() +); +filename = options.appenders.errorFile.filename; +options.appenders.errorFile.filename = filename.replace( + "%p", + CONFIG.FEDERATION_PORT.toString() +); -log4js.configure(options) +log4js.configure(options); -const apolloLogger = log4js.getLogger('apollo') +const apolloLogger = log4js.getLogger("apollo"); // const backendLogger = log4js.getLogger('backend') -const federationLogger = log4js.getLogger('federation') +const federationLogger = log4js.getLogger("federation"); // backendLogger.addContext('user', 'unknown') -export { apolloLogger, federationLogger } +export { apolloLogger, federationLogger }; diff --git a/federation/src/server/plugins.ts b/federation/src/server/plugins.ts index 24df45baa..3cbcc6bef 100644 --- a/federation/src/server/plugins.ts +++ b/federation/src/server/plugins.ts @@ -1,61 +1,69 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import clonedeep from 'lodash.clonedeep' +import clonedeep from "lodash.clonedeep"; const setHeadersPlugin = { requestDidStart() { return { willSendResponse(requestContext: any) { - const { setHeaders = [] } = requestContext.context + const { setHeaders = [] } = requestContext.context; setHeaders.forEach(({ key, value }: { [key: string]: string }) => { if (requestContext.response.http.headers.get(key)) { - requestContext.response.http.headers.set(key, value) + requestContext.response.http.headers.set(key, value); } else { - requestContext.response.http.headers.append(key, value) + requestContext.response.http.headers.append(key, value); } - }) - return requestContext + }); + return requestContext; }, - } + }; }, -} +}; const filterVariables = (variables: any) => { - const vars = clonedeep(variables) - if (vars.password) vars.password = '***' - if (vars.passwordNew) vars.passwordNew = '***' - return vars -} + const vars = clonedeep(variables); + if (vars.password) vars.password = "***"; + if (vars.passwordNew) vars.passwordNew = "***"; + return vars; +}; const logPlugin = { requestDidStart(requestContext: any) { - const { logger } = requestContext - const { query, mutation, variables, operationName } = requestContext.request - if (operationName !== 'IntrospectionQuery') { + const { logger } = requestContext; + const { query, mutation, variables, operationName } = + requestContext.request; + if (operationName !== "IntrospectionQuery") { logger.info(`Request: -${mutation || query}variables: ${JSON.stringify(filterVariables(variables), null, 2)}`) +${mutation || query}variables: ${JSON.stringify( + filterVariables(variables), + null, + 2 + )}`); } return { willSendResponse(requestContext: any) { - if (operationName !== 'IntrospectionQuery') { - if (requestContext.context.user) logger.info(`User ID: ${requestContext.context.user.id}`) + if (operationName !== "IntrospectionQuery") { + if (requestContext.context.user) + logger.info(`User ID: ${requestContext.context.user.id}`); if (requestContext.response.data) { - logger.info('Response Success!') + logger.info("Response Success!"); logger.trace(`Response-Data: -${JSON.stringify(requestContext.response.data, null, 2)}`) +${JSON.stringify(requestContext.response.data, null, 2)}`); } if (requestContext.response.errors) logger.error(`Response-Errors: -${JSON.stringify(requestContext.response.errors, null, 2)}`) +${JSON.stringify(requestContext.response.errors, null, 2)}`); } - return requestContext + return requestContext; }, - } + }; }, -} +}; const plugins = - process.env.NODE_ENV === 'development' ? [setHeadersPlugin] : [setHeadersPlugin, logPlugin] + process.env.NODE_ENV === "development" + ? [setHeadersPlugin] + : [setHeadersPlugin, logPlugin]; -export default plugins +export default plugins; diff --git a/federation/src/typeorm/DBVersion.ts b/federation/src/typeorm/DBVersion.ts index bdb909c1d..8f1fccd5a 100644 --- a/federation/src/typeorm/DBVersion.ts +++ b/federation/src/typeorm/DBVersion.ts @@ -1,27 +1,27 @@ -import { Migration } from '@entity/Migration' -import { federationLogger as logger } from '@/server/logger' +import { Migration } from "@entity/Migration"; +import { federationLogger as logger } from "@/server/logger"; const getDBVersion = async (): Promise => { try { - const dbVersion = await Migration.findOne({ order: { version: 'DESC' } }) - return dbVersion ? dbVersion.fileName : null + const dbVersion = await Migration.findOne({ order: { version: "DESC" } }); + return dbVersion ? dbVersion.fileName : null; } catch (error) { - logger.error(error) - return null + logger.error(error); + return null; } -} +}; const checkDBVersion = async (DB_VERSION: string): Promise => { - const dbVersion = await getDBVersion() + const dbVersion = await getDBVersion(); if (!dbVersion || dbVersion.indexOf(DB_VERSION) === -1) { logger.error( `Wrong database version detected - the backend requires '${DB_VERSION}' but found '${ - dbVersion || 'None' - }`, - ) - return false + dbVersion || "None" + }` + ); + return false; } - return true -} + return true; +}; -export { checkDBVersion, getDBVersion } +export { checkDBVersion, getDBVersion }; diff --git a/federation/src/typeorm/connection.ts b/federation/src/typeorm/connection.ts index d08d935d4..a6a149e3a 100644 --- a/federation/src/typeorm/connection.ts +++ b/federation/src/typeorm/connection.ts @@ -1,14 +1,14 @@ // TODO This is super weird - since the entities are defined in another project they have their own globals. // We cannot use our connection here, but must use the external typeorm installation -import { Connection, createConnection, FileLogger } from '@dbTools/typeorm' -import CONFIG from '@/config' -import { entities } from '@entity/index' +import { Connection, createConnection, FileLogger } from "@dbTools/typeorm"; +import CONFIG from "@/config"; +import { entities } from "@entity/index"; const connection = async (): Promise => { try { return createConnection({ - name: 'default', - type: 'mysql', + name: "default", + type: "mysql", host: CONFIG.DB_HOST, port: CONFIG.DB_PORT, username: CONFIG.DB_USER, @@ -17,18 +17,18 @@ const connection = async (): Promise => { entities, synchronize: false, logging: true, - logger: new FileLogger('all', { + logger: new FileLogger("all", { logPath: CONFIG.TYPEORM_LOGGING_RELATIVE_PATH, }), extra: { - charset: 'utf8mb4_unicode_ci', + charset: "utf8mb4_unicode_ci", }, - }) + }); } catch (error) { // eslint-disable-next-line no-console - console.log(error) - return null + console.log(error); + return null; } -} +}; -export default connection +export default connection;