diff --git a/backend/.env.dist b/backend/.env.dist index 780e60e5a..ae89985e3 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -1,57 +1,60 @@ -CONFIG_VERSION=v8.2022-06-20 - -# Server -PORT=4000 -JWT_SECRET=secret123 -JWT_EXPIRES_IN=10m -GRAPHIQL=false -GDT_API_URL=https://gdt.gradido.net - -# Database -DB_HOST=localhost -DB_PORT=3306 -DB_USER=root -DB_PASSWORD= -DB_DATABASE=gradido_community -TYPEORM_LOGGING_RELATIVE_PATH=typeorm.backend.log - -# Klicktipp -KLICKTIPP=false -KLICKTTIPP_API_URL=https://api.klicktipp.com -KLICKTIPP_USER=gradido_test -KLICKTIPP_PASSWORD=secret321 -KLICKTIPP_APIKEY_DE=SomeFakeKeyDE -KLICKTIPP_APIKEY_EN=SomeFakeKeyEN - -# Community -COMMUNITY_NAME=Gradido Entwicklung -COMMUNITY_URL=http://localhost/ -COMMUNITY_REGISTER_URL=http://localhost/register -COMMUNITY_REDEEM_URL=http://localhost/redeem/{code} -COMMUNITY_REDEEM_CONTRIBUTION_URL=http://localhost/redeem/CL-{code} -COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. - -# Login Server -LOGIN_APP_SECRET=21ffbbc616fe -LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a - -# EMail -EMAIL=false -EMAIL_USERNAME=gradido_email -EMAIL_SENDER=info@gradido.net -EMAIL_PASSWORD=xxx -EMAIL_SMTP_URL=gmail.com -EMAIL_SMTP_PORT=587 -EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} -EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin} -EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password -EMAIL_LINK_OVERVIEW=http://localhost/overview -EMAIL_CODE_VALID_TIME=1440 -EMAIL_CODE_REQUEST_TIME=10 - -# Webhook -WEBHOOK_ELOPAGE_SECRET=secret - -# SET LOG LEVEL AS NEEDED IN YOUR .ENV -# POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal -# LOG_LEVEL=info +CONFIG_VERSION=v9.2022-07-07 + +# Server +PORT=4000 +JWT_SECRET=secret123 +JWT_EXPIRES_IN=10m +GRAPHIQL=false +GDT_API_URL=https://gdt.gradido.net + +# Database +DB_HOST=localhost +DB_PORT=3306 +DB_USER=root +DB_PASSWORD= +DB_DATABASE=gradido_community +TYPEORM_LOGGING_RELATIVE_PATH=typeorm.backend.log + +# Klicktipp +KLICKTIPP=false +KLICKTTIPP_API_URL=https://api.klicktipp.com +KLICKTIPP_USER=gradido_test +KLICKTIPP_PASSWORD=secret321 +KLICKTIPP_APIKEY_DE=SomeFakeKeyDE +KLICKTIPP_APIKEY_EN=SomeFakeKeyEN + +# Community +COMMUNITY_NAME=Gradido Entwicklung +COMMUNITY_URL=http://localhost/ +COMMUNITY_REGISTER_URL=http://localhost/register +COMMUNITY_REDEEM_URL=http://localhost/redeem/{code} +COMMUNITY_REDEEM_CONTRIBUTION_URL=http://localhost/redeem/CL-{code} +COMMUNITY_DESCRIPTION=Die lokale Entwicklungsumgebung von Gradido. + +# Login Server +LOGIN_APP_SECRET=21ffbbc616fe +LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a + +# EMail +EMAIL=false +EMAIL_USERNAME=gradido_email +EMAIL_SENDER=info@gradido.net +EMAIL_PASSWORD=xxx +EMAIL_SMTP_URL=gmail.com +EMAIL_SMTP_PORT=587 +EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} +EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin} +EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password +EMAIL_LINK_OVERVIEW=http://localhost/overview +EMAIL_CODE_VALID_TIME=1440 +EMAIL_CODE_REQUEST_TIME=10 + +# Webhook +WEBHOOK_ELOPAGE_SECRET=secret + +# EventProtocol +EVENT_PROTOCOL_DISABLED=false + +# SET LOG LEVEL AS NEEDED IN YOUR .ENV +# POSSIBLE VALUES: all | trace | debug | info | warn | error | fatal +# LOG_LEVEL=info diff --git a/backend/.env.template b/backend/.env.template index 94bf41550..beaa256ef 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -50,3 +50,6 @@ EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME # Webhook WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET + +# EventProtocol +EVENT_PROTOCOL_DISABLED=$EVENT_PROTOCOL_DISABLED diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 8b84c059d..2120fce71 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -1,123 +1,129 @@ -// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) - -import dotenv from 'dotenv' -import Decimal from 'decimal.js-light' -dotenv.config() - -Decimal.set({ - precision: 25, - rounding: Decimal.ROUND_HALF_UP, -}) - -const constants = { - DB_VERSION: '0042-update_transactions_for_blockchain', - DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 - LOG4JS_CONFIG: 'log4js-config.json', - // default log level on production should be info - LOG_LEVEL: process.env.LOG_LEVEL || 'info', - CONFIG_VERSION: { - DEFAULT: 'DEFAULT', - EXPECTED: 'v8.2022-06-20', - CURRENT: '', - }, -} - -const server = { - PORT: process.env.PORT || 4000, - JWT_SECRET: process.env.JWT_SECRET || 'secret123', - JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m', - 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, -} - -const database = { - 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', -} - -const klicktipp = { - KLICKTIPP: process.env.KLICKTIPP === 'true' || false, - KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL || 'https://api.klicktipp.com', - KLICKTIPP_USER: process.env.KLICKTIPP_USER || 'gradido_test', - KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD || 'secret321', - KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE || 'SomeFakeKeyDE', - KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN || 'SomeFakeKeyEN', -} - -const community = { - COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', - COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/', - 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_CONTRIBUTION_URL: - process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL || 'http://localhost/redeem/CL-{code}', - COMMUNITY_DESCRIPTION: - process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', -} - -const loginServer = { - LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe', - LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a', -} - -const email = { - EMAIL: process.env.EMAIL === 'true' || false, - EMAIL_USERNAME: process.env.EMAIL_USERNAME || 'gradido_email', - EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net', - EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', - EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', - EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', - EMAIL_LINK_VERIFICATION: - process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}', - EMAIL_LINK_SETPASSWORD: - process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}', - EMAIL_LINK_FORGOTPASSWORD: - process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', - EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview', - // time in minutes a optin code is valid - EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME - ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440 - : 1440, - // time in minutes that must pass to request a new optin code - EMAIL_CODE_REQUEST_TIME: process.env.EMAIL_CODE_REQUEST_TIME - ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) || 10 - : 10, -} - -const webhook = { - // Elopage - WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret', -} - -// 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 -if ( - ![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}"`, - ) -} - -const CONFIG = { - ...constants, - ...server, - ...database, - ...klicktipp, - ...community, - ...email, - ...loginServer, - ...webhook, -} - -export default CONFIG +// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env) + +import dotenv from 'dotenv' +import Decimal from 'decimal.js-light' +dotenv.config() + +Decimal.set({ + precision: 25, + rounding: Decimal.ROUND_HALF_UP, +}) + +const constants = { + DB_VERSION: '0043-add_event_protocol_table', + DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 + LOG4JS_CONFIG: 'log4js-config.json', + // default log level on production should be info + LOG_LEVEL: process.env.LOG_LEVEL || 'info', + CONFIG_VERSION: { + DEFAULT: 'DEFAULT', + EXPECTED: 'v9.2022-07-07', + CURRENT: '', + }, +} + +const server = { + PORT: process.env.PORT || 4000, + JWT_SECRET: process.env.JWT_SECRET || 'secret123', + JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m', + 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, +} + +const database = { + 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', +} + +const klicktipp = { + KLICKTIPP: process.env.KLICKTIPP === 'true' || false, + KLICKTTIPP_API_URL: process.env.KLICKTIPP_API_URL || 'https://api.klicktipp.com', + KLICKTIPP_USER: process.env.KLICKTIPP_USER || 'gradido_test', + KLICKTIPP_PASSWORD: process.env.KLICKTIPP_PASSWORD || 'secret321', + KLICKTIPP_APIKEY_DE: process.env.KLICKTIPP_APIKEY_DE || 'SomeFakeKeyDE', + KLICKTIPP_APIKEY_EN: process.env.KLICKTIPP_APIKEY_EN || 'SomeFakeKeyEN', +} + +const community = { + COMMUNITY_NAME: process.env.COMMUNITY_NAME || 'Gradido Entwicklung', + COMMUNITY_URL: process.env.COMMUNITY_URL || 'http://localhost/', + 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_CONTRIBUTION_URL: + process.env.COMMUNITY_REDEEM_CONTRIBUTION_URL || 'http://localhost/redeem/CL-{code}', + COMMUNITY_DESCRIPTION: + process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', +} + +const loginServer = { + LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe', + LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a', +} + +const email = { + EMAIL: process.env.EMAIL === 'true' || false, + EMAIL_USERNAME: process.env.EMAIL_USERNAME || 'gradido_email', + EMAIL_SENDER: process.env.EMAIL_SENDER || 'info@gradido.net', + EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', + EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', + EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', + EMAIL_LINK_VERIFICATION: + process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}', + EMAIL_LINK_SETPASSWORD: + process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}', + EMAIL_LINK_FORGOTPASSWORD: + process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', + EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview', + // time in minutes a optin code is valid + EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME + ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440 + : 1440, + // time in minutes that must pass to request a new optin code + EMAIL_CODE_REQUEST_TIME: process.env.EMAIL_CODE_REQUEST_TIME + ? parseInt(process.env.EMAIL_CODE_REQUEST_TIME) || 10 + : 10, +} + +const webhook = { + // Elopage + WEBHOOK_ELOPAGE_SECRET: process.env.WEBHOOK_ELOPAGE_SECRET || 'secret', +} + +const eventProtocol = { + // 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 +if ( + ![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}"`, + ) +} + +const CONFIG = { + ...constants, + ...server, + ...database, + ...klicktipp, + ...community, + ...email, + ...loginServer, + ...webhook, + ...eventProtocol, +} + +export default CONFIG diff --git a/backend/src/event/Event.ts b/backend/src/event/Event.ts new file mode 100644 index 000000000..6f07661f1 --- /dev/null +++ b/backend/src/event/Event.ts @@ -0,0 +1,301 @@ +import { EventProtocol } from '@entity/EventProtocol' +import decimal from 'decimal.js-light' +import { EventProtocolType } from './EventProtocolType' + +export class EventBasic { + type: string + createdAt: Date +} +export class EventBasicUserId extends EventBasic { + userId: number +} + +export class EventBasicTx extends EventBasicUserId { + xUserId: number + xCommunityId: number + transactionId: number + amount: decimal +} + +export class EventBasicCt extends EventBasicUserId { + contributionId: number + amount: decimal +} + +export class EventBasicRedeem extends EventBasicUserId { + transactionId?: number + contributionId?: number +} + +export class EventVisitGradido extends EventBasic {} +export class EventRegister extends EventBasicUserId {} +export class EventRedeemRegister extends EventBasicRedeem {} +export class EventInactiveAccount extends EventBasicUserId {} +export class EventSendConfirmationEmail extends EventBasicUserId {} +export class EventConfirmationEmail extends EventBasicUserId {} +export class EventRegisterEmailKlicktipp extends EventBasicUserId {} +export class EventLogin extends EventBasicUserId {} +export class EventRedeemLogin extends EventBasicRedeem {} +export class EventActivateAccount extends EventBasicUserId {} +export class EventPasswordChange extends EventBasicUserId {} +export class EventTransactionSend extends EventBasicTx {} +export class EventTransactionSendRedeem extends EventBasicTx {} +export class EventTransactionRepeateRedeem extends EventBasicTx {} +export class EventTransactionCreation extends EventBasicUserId { + transactionId: number + amount: decimal +} +export class EventTransactionReceive extends EventBasicTx {} +export class EventTransactionReceiveRedeem extends EventBasicTx {} +export class EventContributionCreate extends EventBasicCt {} +export class EventContributionConfirm extends EventBasicCt { + xUserId: number + xCommunityId: number +} +export class EventContributionLinkDefine extends EventBasicCt {} +export class EventContributionLinkActivateRedeem extends EventBasicCt {} + +export class Event { + constructor() + constructor(event?: EventProtocol) { + if (event) { + this.id = event.id + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.xUserId = event.xUserId + this.xCommunityId = event.xCommunityId + this.transactionId = event.transactionId + this.contributionId = event.contributionId + this.amount = event.amount + } + } + + public setEventBasic(): Event { + this.type = EventProtocolType.BASIC + this.createdAt = new Date() + + return this + } + + public setEventVisitGradido(): Event { + this.setEventBasic() + this.type = EventProtocolType.VISIT_GRADIDO + + return this + } + + public setEventRegister(ev: EventRegister): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.REGISTER + + return this + } + + public setEventRedeemRegister(ev: EventRedeemRegister): Event { + this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) + this.type = EventProtocolType.REDEEM_REGISTER + + return this + } + + public setEventInactiveAccount(ev: EventInactiveAccount): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.INACTIVE_ACCOUNT + + return this + } + + public setEventSendConfirmationEmail(ev: EventSendConfirmationEmail): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.SEND_CONFIRMATION_EMAIL + + return this + } + + public setEventConfirmationEmail(ev: EventConfirmationEmail): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.CONFIRM_EMAIL + + return this + } + + public setEventRegisterEmailKlicktipp(ev: EventRegisterEmailKlicktipp): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.REGISTER_EMAIL_KLICKTIPP + + return this + } + + public setEventLogin(ev: EventLogin): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.LOGIN + + return this + } + + public setEventRedeemLogin(ev: EventRedeemLogin): Event { + this.setByBasicRedeem(ev.userId, ev.transactionId, ev.contributionId) + this.type = EventProtocolType.REDEEM_LOGIN + + return this + } + + public setEventActivateAccount(ev: EventActivateAccount): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.ACTIVATE_ACCOUNT + + return this + } + + public setEventPasswordChange(ev: EventPasswordChange): Event { + this.setByBasicUser(ev.userId) + this.type = EventProtocolType.PASSWORD_CHANGE + + return this + } + + public setEventTransactionSend(ev: EventTransactionSend): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_SEND + + return this + } + + public setEventTransactionSendRedeem(ev: EventTransactionSendRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_SEND_REDEEM + + return this + } + + public setEventTransactionRepeateRedeem(ev: EventTransactionRepeateRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_REPEATE_REDEEM + + return this + } + + public setEventTransactionCreation(ev: EventTransactionCreation): Event { + this.setByBasicUser(ev.userId) + if (ev.transactionId) this.transactionId = ev.transactionId + if (ev.amount) this.amount = ev.amount + this.type = EventProtocolType.TRANSACTION_CREATION + + return this + } + + public setEventTransactionReceive(ev: EventTransactionReceive): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_RECEIVE + + return this + } + + public setEventTransactionReceiveRedeem(ev: EventTransactionReceiveRedeem): Event { + this.setByBasicTx(ev.userId, ev.xUserId, ev.xCommunityId, ev.transactionId, ev.amount) + this.type = EventProtocolType.TRANSACTION_RECEIVE_REDEEM + + return this + } + + public setEventContributionCreate(ev: EventContributionCreate): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_CREATE + + return this + } + + public setEventContributionConfirm(ev: EventContributionConfirm): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + if (ev.xUserId) this.xUserId = ev.xUserId + if (ev.xCommunityId) this.xCommunityId = ev.xCommunityId + this.type = EventProtocolType.CONTRIBUTION_CONFIRM + + return this + } + + public setEventContributionLinkDefine(ev: EventContributionLinkDefine): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_LINK_DEFINE + + return this + } + + public setEventContributionLinkActivateRedeem(ev: EventContributionLinkActivateRedeem): Event { + this.setByBasicCt(ev.userId, ev.contributionId, ev.amount) + this.type = EventProtocolType.CONTRIBUTION_LINK_ACTIVATE_REDEEM + + return this + } + + setByBasicUser(userId: number): Event { + this.setEventBasic() + this.userId = userId + + return this + } + + setByBasicTx( + userId: number, + xUserId?: number, + xCommunityId?: number, + transactionId?: number, + amount?: decimal, + ): Event { + this.setByBasicUser(userId) + if (xUserId) this.xUserId = xUserId + if (xCommunityId) this.xCommunityId = xCommunityId + if (transactionId) this.transactionId = transactionId + if (amount) this.amount = amount + + return this + } + + setByBasicCt(userId: number, contributionId: number, amount?: decimal): Event { + this.setByBasicUser(userId) + if (contributionId) this.contributionId = contributionId + if (amount) this.amount = amount + + return this + } + + setByBasicRedeem(userId: number, transactionId?: number, contributionId?: number): Event { + this.setByBasicUser(userId) + if (transactionId) this.transactionId = transactionId + if (contributionId) this.contributionId = contributionId + + return this + } + + setByEventTransactionCreation(event: EventTransactionCreation): Event { + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.transactionId = event.transactionId + this.amount = event.amount + + return this + } + + setByEventContributionConfirm(event: EventContributionConfirm): Event { + this.type = event.type + this.createdAt = event.createdAt + this.userId = event.userId + this.xUserId = event.xUserId + this.xCommunityId = event.xCommunityId + this.amount = event.amount + + return this + } + + id: number + type: string + createdAt: Date + userId: number + xUserId?: number + xCommunityId?: number + transactionId?: number + contributionId?: number + amount?: decimal +} diff --git a/backend/src/event/EventProtocolEmitter.ts b/backend/src/event/EventProtocolEmitter.ts new file mode 100644 index 000000000..6dea99810 --- /dev/null +++ b/backend/src/event/EventProtocolEmitter.ts @@ -0,0 +1,39 @@ +import { Event } from '@/event/Event' +import { backendLogger as logger } from '@/server/logger' +import { EventProtocol } from '@entity/EventProtocol' +import CONFIG from '@/config' + +class EventProtocolEmitter { + /* }extends EventEmitter { */ + private events: Event[] + + public addEvent(event: Event) { + this.events.push(event) + } + + public getEvents(): Event[] { + return this.events + } + + public isDisabled() { + logger.info(`EventProtocol - isDisabled=${CONFIG.EVENT_PROTOCOL_DISABLED}`) + return CONFIG.EVENT_PROTOCOL_DISABLED === true + } + + public async writeEvent(event: Event): Promise { + if (!eventProtocol.isDisabled()) { + logger.info(`writeEvent(${JSON.stringify(event)})`) + const dbEvent = new EventProtocol() + dbEvent.type = event.type + dbEvent.createdAt = event.createdAt + dbEvent.userId = event.userId + if (event.xUserId) dbEvent.xUserId = event.xUserId + if (event.xCommunityId) dbEvent.xCommunityId = event.xCommunityId + if (event.contributionId) dbEvent.contributionId = event.contributionId + if (event.transactionId) dbEvent.transactionId = event.transactionId + if (event.amount) dbEvent.amount = event.amount + await dbEvent.save() + } + } +} +export const eventProtocol = new EventProtocolEmitter() diff --git a/backend/src/event/EventProtocolType.ts b/backend/src/event/EventProtocolType.ts new file mode 100644 index 000000000..0f61f787a --- /dev/null +++ b/backend/src/event/EventProtocolType.ts @@ -0,0 +1,24 @@ +export enum EventProtocolType { + BASIC = 'BASIC', + VISIT_GRADIDO = 'VISIT_GRADIDO', + REGISTER = 'REGISTER', + REDEEM_REGISTER = 'REDEEM_REGISTER', + INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT', + SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL', + CONFIRM_EMAIL = 'CONFIRM_EMAIL', + REGISTER_EMAIL_KLICKTIPP = 'REGISTER_EMAIL_KLICKTIPP', + LOGIN = 'LOGIN', + REDEEM_LOGIN = 'REDEEM_LOGIN', + ACTIVATE_ACCOUNT = 'ACTIVATE_ACCOUNT', + PASSWORD_CHANGE = 'PASSWORD_CHANGE', + TRANSACTION_SEND = 'TRANSACTION_SEND', + TRANSACTION_SEND_REDEEM = 'TRANSACTION_SEND_REDEEM', + TRANSACTION_REPEATE_REDEEM = 'TRANSACTION_REPEATE_REDEEM', + TRANSACTION_CREATION = 'TRANSACTION_CREATION', + TRANSACTION_RECEIVE = 'TRANSACTION_RECEIVE', + TRANSACTION_RECEIVE_REDEEM = 'TRANSACTION_RECEIVE_REDEEM', + CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE', + CONTRIBUTION_CONFIRM = 'CONTRIBUTION_CONFIRM', + CONTRIBUTION_LINK_DEFINE = 'CONTRIBUTION_LINK_DEFINE', + CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM', +} diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 5b824b38f..a89a8cb0b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -23,6 +23,14 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' import { hasElopageBuys } from '@/util/hasElopageBuys' +import { eventProtocol } from '@/event/EventProtocolEmitter' +import { + Event, + EventLogin, + EventRedeemRegister, + EventRegister, + EventSendConfirmationEmail, +} from '@/event/Event' import { getUserCreation } from './util/creations' // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -291,6 +299,9 @@ export class UserResolver { key: 'token', value: encode(dbUser.pubKey), }) + const ev = new EventLogin() + ev.userId = user.id + eventProtocol.writeEvent(new Event().setEventLogin(ev)) logger.info('successful Login:' + user) return user } @@ -368,6 +379,9 @@ export class UserResolver { // const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) const emailHash = getEmailHash(email) + const eventRegister = new EventRegister() + const eventRedeemRegister = new EventRedeemRegister() + const eventSendConfirmEmail = new EventSendConfirmationEmail() const dbUser = new DbUser() dbUser.email = email dbUser.firstName = firstName @@ -385,12 +399,14 @@ export class UserResolver { logger.info('redeemCode found contributionLink=' + contributionLink) if (contributionLink) { dbUser.contributionLinkId = contributionLink.id + eventRedeemRegister.contributionId = contributionLink.id } } else { const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) logger.info('redeemCode found transactionLink=' + transactionLink) if (transactionLink) { dbUser.referrerId = transactionLink.userId + eventRedeemRegister.transactionId = transactionLink.id } } } @@ -401,6 +417,7 @@ export class UserResolver { // loginUser.pubKey = keyPair[0] // loginUser.privKey = encryptedPrivkey + const event = new Event() const queryRunner = getConnection().createQueryRunner() await queryRunner.connect() await queryRunner.startTransaction('READ UNCOMMITTED') @@ -430,6 +447,9 @@ export class UserResolver { duration: printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME), }) logger.info(`sendAccountActivationEmail of ${firstName}.${lastName} to ${email}`) + eventSendConfirmEmail.userId = dbUser.id + eventProtocol.writeEvent(event.setEventSendConfirmationEmail(eventSendConfirmEmail)) + /* uncomment this, when you need the activation link on the console */ // In case EMails are disabled log the activation link for the user if (!emailSent) { @@ -446,6 +466,14 @@ export class UserResolver { } logger.info('createUser() successful...') + if (redeemCode) { + eventRedeemRegister.userId = dbUser.id + eventProtocol.writeEvent(event.setEventRedeemRegister(eventRedeemRegister)) + } else { + eventRegister.userId = dbUser.id + eventProtocol.writeEvent(event.setEventRegister(eventRegister)) + } + return new User(dbUser) } diff --git a/database/entity/0043-add_event_protocol_table/EventProtocol.ts b/database/entity/0043-add_event_protocol_table/EventProtocol.ts new file mode 100644 index 000000000..72470d2ed --- /dev/null +++ b/database/entity/0043-add_event_protocol_table/EventProtocol.ts @@ -0,0 +1,39 @@ +import Decimal from 'decimal.js-light' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' + +@Entity('event_protocol') +export class EventProtocol extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ length: 100, nullable: false, collation: 'utf8mb4_unicode_ci' }) + type: string + + @Column({ name: 'created_at', type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date + + @Column({ name: 'user_id', unsigned: true, nullable: false }) + userId: number + + @Column({ name: 'x_user_id', unsigned: true, nullable: true }) + xUserId: number + + @Column({ name: 'x_community_id', unsigned: true, nullable: true }) + xCommunityId: number + + @Column({ name: 'transaction_id', unsigned: true, nullable: true }) + transactionId: number + + @Column({ name: 'contribution_id', unsigned: true, nullable: true }) + contributionId: number + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: true, + transformer: DecimalTransformer, + }) + amount: Decimal +} diff --git a/database/entity/EventProtocol.ts b/database/entity/EventProtocol.ts new file mode 100644 index 000000000..4a73f146c --- /dev/null +++ b/database/entity/EventProtocol.ts @@ -0,0 +1 @@ +export { EventProtocol } from './0043-add_event_protocol_table/EventProtocol' diff --git a/database/entity/index.ts b/database/entity/index.ts index 266c40740..733c99a3a 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -6,6 +6,7 @@ import { Transaction } from './Transaction' import { TransactionLink } from './TransactionLink' import { User } from './User' import { Contribution } from './Contribution' +import { EventProtocol } from './EventProtocol' export const entities = [ Contribution, @@ -16,4 +17,5 @@ export const entities = [ Transaction, TransactionLink, User, + EventProtocol, ] diff --git a/database/migrations/0043-add_event_protocol_table.ts b/database/migrations/0043-add_event_protocol_table.ts new file mode 100644 index 000000000..c3669f857 --- /dev/null +++ b/database/migrations/0043-add_event_protocol_table.ts @@ -0,0 +1,28 @@ +/* MIGRATION TO ADD EVENT_PROTOCOL + * + * This migration adds the table `event_protocol` in order to store all sorts of business event data + */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(` + CREATE TABLE IF NOT EXISTS \`event_protocol\` ( + \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, + \`type\` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, + \`created_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + \`user_id\` int(10) unsigned NOT NULL, + \`x_user_id\` int(10) unsigned NULL DEFAULT NULL, + \`x_community_id\` int(10) unsigned NULL DEFAULT NULL, + \`transaction_id\` int(10) unsigned NULL DEFAULT NULL, + \`contribution_id\` int(10) unsigned NULL DEFAULT NULL, + \`amount\` bigint(20) NULL DEFAULT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // write downgrade logic as parameter of queryFn + await queryFn(`DROP TABLE IF EXISTS \`event_protocol\`;`) +} diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index edb878040..d53ffebbe 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -1,80 +1,84 @@ -GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log - -# start script -DEPLOY_SEED_DATA=false - -# nginx -NGINX_REWRITE_LEGACY_URLS=true -NGINX_SSL=true -NGINX_SERVER_NAME=stage1.gradido.net -NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem -NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem -NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem -NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf -NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page - -# webhook -WEBHOOK_GITHUB_SECRET=secret -WEBHOOK_GITHUB_BRANCH=master - -# community -COMMUNITY_NAME="Gradido Development Stage1" -COMMUNITY_URL=https://stage1.gradido.net/ -COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register -COMMUNITY_REDEEM_URL=https://stage1.gradido.net/redeem/{code} -COMMUNITY_REDEEM_CONTRIBUTION_URL=https://stage1.gradido.net/redeem/CL-{code} -COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" - -# backend -BACKEND_CONFIG_VERSION=v8.2022-06-20 - -JWT_EXPIRES_IN=10m -GDT_API_URL=https://gdt.gradido.net - -TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log - -KLICKTIPP=false -KLICKTIPP_USER= -KLICKTIPP_PASSWORD= -KLICKTIPP_APIKEY_DE= -KLICKTIPP_APIKEY_EN= - -EMAIL=true -EMAIL_USERNAME=peter@lustig.de -EMAIL_SENDER=peter@lustig.de -EMAIL_PASSWORD=1234 -EMAIL_SMTP_URL=smtp.lustig.de -EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code} -EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin} -EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password -EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview -EMAIL_CODE_VALID_TIME=1440 -EMAIL_CODE_REQUEST_TIME=10 - -WEBHOOK_ELOPAGE_SECRET=secret - -# database -DATABASE_CONFIG_VERSION=v1.2022-03-18 - -# frontend -FRONTEND_CONFIG_VERSION=v2.2022-04-07 - -GRAPHQL_URI=https://stage1.gradido.net/graphql -ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token} - -DEFAULT_PUBLISHER_ID=2896 - -META_URL=http://localhost -META_TITLE_DE="Gradido – Dein Dankbarkeitskonto" -META_TITLE_EN="Gradido - Your gratitude account" -META_DESCRIPTION_DE="Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle." -META_DESCRIPTION_EN="Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all." -META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem" -META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System" -META_AUTHOR="Bernd Hückstädt - Gradido-Akademie" - -# admin -ADMIN_CONFIG_VERSION=v1.2022-03-18 - -WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token} +GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log + +# start script +DEPLOY_SEED_DATA=false + +# nginx +NGINX_REWRITE_LEGACY_URLS=true +NGINX_SSL=true +NGINX_SERVER_NAME=stage1.gradido.net +NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem +NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem +NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem +NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf +NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page + +# webhook +WEBHOOK_GITHUB_SECRET=secret +WEBHOOK_GITHUB_BRANCH=master + +# community +COMMUNITY_NAME="Gradido Development Stage1" +COMMUNITY_URL=https://stage1.gradido.net/ +COMMUNITY_REGISTER_URL=https://stage1.gradido.net/register +COMMUNITY_REDEEM_URL=https://stage1.gradido.net/redeem/{code} +COMMUNITY_REDEEM_CONTRIBUTION_URL=https://stage1.gradido.net/redeem/CL-{code} +COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" + +# backend +BACKEND_CONFIG_VERSION=v9.2022-07-07 + +JWT_EXPIRES_IN=10m +GDT_API_URL=https://gdt.gradido.net + +TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log + +KLICKTIPP=false +KLICKTIPP_USER= +KLICKTIPP_PASSWORD= +KLICKTIPP_APIKEY_DE= +KLICKTIPP_APIKEY_EN= + +EMAIL=true +EMAIL_USERNAME=peter@lustig.de +EMAIL_SENDER=peter@lustig.de +EMAIL_PASSWORD=1234 +EMAIL_SMTP_URL=smtp.lustig.de +EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code} +EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin} +EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password +EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview +EMAIL_CODE_VALID_TIME=1440 +EMAIL_CODE_REQUEST_TIME=10 + +WEBHOOK_ELOPAGE_SECRET=secret + +# EventProtocol +EVENT_PROTOCOL_DISABLED=false + + +# database +DATABASE_CONFIG_VERSION=v1.2022-03-18 + +# frontend +FRONTEND_CONFIG_VERSION=v2.2022-04-07 + +GRAPHQL_URI=https://stage1.gradido.net/graphql +ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token} + +DEFAULT_PUBLISHER_ID=2896 + +META_URL=http://localhost +META_TITLE_DE="Gradido – Dein Dankbarkeitskonto" +META_TITLE_EN="Gradido - Your gratitude account" +META_DESCRIPTION_DE="Dankbarkeit ist die Währung der neuen Zeit. Immer mehr Menschen entfalten ihr Potenzial und gestalten eine gute Zukunft für alle." +META_DESCRIPTION_EN="Gratitude is the currency of the new age. More and more people are unleashing their potential and shaping a good future for all." +META_KEYWORDS_DE="Grundeinkommen, Währung, Dankbarkeit, Schenk-Ökonomie, Natürliche Ökonomie des Lebens, Ökonomie, Ökologie, Potenzialentfaltung, Schenken und Danken, Kreislauf des Lebens, Geldsystem" +META_KEYWORDS_EN="Basic Income, Currency, Gratitude, Gift Economy, Natural Economy of Life, Economy, Ecology, Potential Development, Giving and Thanking, Cycle of Life, Monetary System" +META_AUTHOR="Bernd Hückstädt - Gradido-Akademie" + +# admin +ADMIN_CONFIG_VERSION=v1.2022-03-18 + +WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token} WALLET_URL=https://stage1.gradido.net/login \ No newline at end of file diff --git a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md index 5a436d057..f8cf2cd03 100644 --- a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md +++ b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md @@ -6,29 +6,30 @@ With the business event protocol the gradido application will capture and persis The different event types will be defined as Enum. The following list is a first draft and will grow with further event types in the future. -| EventType | Value | Description | -| --------------------------- | ----- | ---------------------------------------------------------------------------------------------------- | -| BasicEvent | 0 | the basic event is the root of all further extending event types | -| VisitGradidoEvent | 10 | if a user visits a gradido page without login or register | -| RegisterEvent | 20 | the user presses the register button | -| RedeemRegisterEvent | 21 | the user presses the register button initiated by the redeem link | -| InActiveAccountEvent | 22 | the systems create an inactive account during the register process | -| SendConfirmEmailEvent | 23 | the system send a confirmation email to the user during the register process | -| ConfirmEmailEvent | 24 | the user confirms his email during the register process | -| RegisterEmailKlickTippEvent | 25 | the system registers the confirmed email at klicktipp | -| LoginEvent | 30 | the user presses the login button | -| RedeemLoginEvent | 31 | the user presses the login button initiated by the redeem link | -| ActivateAccountEvent | 32 | the system activates the users account during the first login process | -| PasswordChangeEvent | 33 | the user changes his password | -| TxSendEvent | 40 | the user creates a transaction and sends it online | -| TxSendRedeemEvent | 41 | the user creates a transaction and sends it per redeem link | -| TxRepeateRedeemEvent | 42 | the user recreates a redeem link of a still open transaction | -| TxCreationEvent | 50 | the user receives a creation transaction for his confirmed contribution | -| TxReceiveEvent | 51 | the user receives a transaction from an other user and posts the amount on his account | -| TxReceiveRedeemEvent | 52 | the user activates the redeem link and receives the transaction and posts the amount on his account | -| ContribCreateEvent | 60 | the user enters his contribution and asks for confirmation | -| ContribConfirmEvent | 61 | the user confirms a contribution of an other user (for future multi confirmation from several users) | -| | | | +| EventType | Value | Description | +| ----------------------------------- | ----- | ------------------------------------------------------------------------------------------------------ | +| BasicEvent | 0 | the basic event is the root of all further extending event types | +| VisitGradidoEvent | 10 | if a user visits a gradido page without login or register | +| RegisterEvent | 20 | the user presses the register button | +| RedeemRegisterEvent | 21 | the user presses the register button initiated by the redeem link | +| InActiveAccountEvent | 22 | the systems create an inactive account during the register process | +| SendConfirmEmailEvent | 23 | the system send a confirmation email to the user during the register process | +| ConfirmEmailEvent | 24 | the user confirms his email during the register process | +| RegisterEmailKlickTippEvent | 25 | the system registers the confirmed email at klicktipp | +| LoginEvent | 30 | the user presses the login button | +| RedeemLoginEvent | 31 | the user presses the login button initiated by the redeem link | +| ActivateAccountEvent | 32 | the system activates the users account during the first login process | +| PasswordChangeEvent | 33 | the user changes his password | +| TransactionSendEvent | 40 | the user creates a transaction and sends it online | +| TransactionSendRedeemEvent | 41 | the user creates a transaction and sends it per redeem link | +| TransactionRepeateRedeemEvent | 42 | the user recreates a redeem link of a still open transaction | +| TransactionCreationEvent | 50 | the user receives a creation transaction for his confirmed contribution | +| TransactionReceiveEvent | 51 | the user receives a transaction from an other user and posts the amount on his account | +| TransactionReceiveRedeemEvent | 52 | the user activates the redeem link and receives the transaction and posts the amount on his account | +| ContributionCreateEvent | 60 | the user enters his contribution and asks for confirmation | +| ContributionConfirmEvent | 61 | the user confirms a contribution of an other user (for future multi confirmation from several users) | +| ContributionLinkDefineEvent | 70 | the admin user defines a contributionLink, which could be send per Link/QR-Code on an other medium | +| ContributionLinkActivateRedeemEvent | 71 | the user activates a received contributionLink to create a contribution entry for the contributionLink | ## EventProtocol - Entity @@ -50,29 +51,30 @@ The business events will be stored in database in the new table `EventProtocol`. The following table lists for each event type the mandatory attributes, which have to be initialized at event occurence and to be written in the database event protocol table: -| EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | -| :-------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: | -| BasicEvent | x | x | x | | | | | | | -| VisitGradidoEvent | x | x | x | | | | | | | -| RegisterEvent | x | x | x | x | | | | | | -| RedeemRegisterEvent | x | x | x | x | | | | | | -| InActiveAccountEvent | x | x | x | x | | | | | | -| SendConfirmEmailEvent | x | x | x | x | | | | | | -| ConfirmEmailEvent | x | x | x | x | | | | | | -| RegisterEmailKlickTippEvent | x | x | x | x | | | | | | -| LoginEvent | x | x | x | x | | | | | | -| RedeemLoginEvent | x | x | x | x | | | | | | -| ActivateAccountEvent | x | x | x | x | | | | | | -| PasswordChangeEvent | x | x | x | x | | | | | | -| TxSendEvent | x | x | x | x | x | x | x | | x | -| TxSendRedeemEvent | x | x | x | x | x | x | x | | x | -| TxRepeateRedeemEvent | x | x | x | x | x | x | x | | x | -| TxCreationEvent | x | x | x | x | | | x | | x | -| TxReceiveEvent | x | x | x | x | x | x | x | | x | -| TxReceiveRedeemEvent | x | x | x | x | x | x | x | | x | -| ContribCreateEvent | x | x | x | x | | | | x | | -| ContribConfirmEvent | x | x | x | x | x | x | | x | | -| | | | | | | | | | | +| EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | +| :---------------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: | +| BasicEvent | x | x | x | | | | | | | +| VisitGradidoEvent | x | x | x | | | | | | | +| RegisterEvent | x | x | x | x | | | | | | +| RedeemRegisterEvent | x | x | x | x | | | (x) | (x) | | +| InActiveAccountEvent | x | x | x | x | | | | | | +| SendConfirmEmailEvent | x | x | x | x | | | | | | +| ConfirmEmailEvent | x | x | x | x | | | | | | +| RegisterEmailKlickTippEvent | x | x | x | x | | | | | | +| LoginEvent | x | x | x | x | | | | | | +| RedeemLoginEvent | x | x | x | x | | | (x) | (x) | | +| ActivateAccountEvent | x | x | x | x | | | | | | +| PasswordChangeEvent | x | x | x | x | | | | | | +| TransactionSendEvent | x | x | x | x | x | x | x | | x | +| TransactionSendRedeemEvent | x | x | x | x | x | x | x | | x | +| TransactionRepeateRedeemEvent | x | x | x | x | x | x | x | | x | +| TransactionCreationEvent | x | x | x | x | | | x | | x | +| TransactionReceiveEvent | x | x | x | x | x | x | x | | x | +| TransactionReceiveRedeemEvent | x | x | x | x | x | x | x | | x | +| ContributionCreateEvent | x | x | x | x | | | | x | x | +| ContributionConfirmEvent | x | x | x | x | x | x | | x | x | +| ContributionLinkDefineEvent | x | x | x | x | | | | | x | +| ContributionLinkActivateRedeemEvent | x | x | x | x | | | | x | x | ## Event creation