diff --git a/admin/package.json b/admin/package.json
index 3e1522f91..e3c94f5d8 100644
--- a/admin/package.json
+++ b/admin/package.json
@@ -35,6 +35,7 @@
"identity-obj-proxy": "^3.0.0",
"jest": "26.6.3",
"moment": "^2.29.1",
+ "regenerator-runtime": "^0.13.9",
"stats-webpack-plugin": "^0.7.0",
"vue": "^2.6.11",
"vue-apollo": "^3.0.8",
diff --git a/admin/src/App.spec.js b/admin/src/App.spec.js
new file mode 100644
index 000000000..b47141972
--- /dev/null
+++ b/admin/src/App.spec.js
@@ -0,0 +1,68 @@
+import { mount } from '@vue/test-utils'
+import App from './App'
+
+const localVue = global.localVue
+
+const storeCommitMock = jest.fn()
+
+const mocks = {
+ $store: {
+ commit: storeCommitMock,
+ },
+}
+
+const localStorageMock = (() => {
+ let store = {}
+
+ return {
+ getItem: (key) => {
+ return store[key] || null
+ },
+ setItem: (key, value) => {
+ store[key] = value.toString()
+ },
+ removeItem: (key) => {
+ delete store[key]
+ },
+ clear: () => {
+ store = {}
+ },
+ }
+})()
+
+describe('App', () => {
+ let wrapper
+
+ const Wrapper = () => {
+ return mount(App, { localVue, mocks })
+ }
+
+ describe('mount', () => {
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ it('has a div with id "app"', () => {
+ expect(wrapper.find('div#app').exists()).toBeTruthy()
+ })
+ })
+
+ describe('window localStorage is undefined', () => {
+ it('does not commit a token to the store', () => {
+ expect(storeCommitMock).not.toBeCalled()
+ })
+ })
+
+ describe('with token in local storage', () => {
+ beforeEach(() => {
+ Object.defineProperty(window, 'localStorage', {
+ value: localStorageMock,
+ })
+ window.localStorage.setItem('vuex', JSON.stringify({ token: 1234 }))
+ })
+
+ it.skip('commits the token to the store', () => {
+ expect(storeCommitMock).toBeCalledWith('token', 1234)
+ })
+ })
+})
diff --git a/admin/src/App.vue b/admin/src/App.vue
index 70bc2978a..9267cc82b 100644
--- a/admin/src/App.vue
+++ b/admin/src/App.vue
@@ -1,19 +1,9 @@
-
-
-
-
-
+
diff --git a/admin/src/main.js b/admin/src/main.js
index b3925c9fe..aa4cc3e03 100644
--- a/admin/src/main.js
+++ b/admin/src/main.js
@@ -1,6 +1,9 @@
import Vue from 'vue'
import App from './App.vue'
+// without this async calls are not working
+import 'regenerator-runtime'
+
import store from './store/store'
import router from './router/router'
@@ -22,7 +25,9 @@ import moment from 'vue-moment'
const httpLink = new HttpLink({ uri: CONFIG.GRAPHQL_URI })
const authLink = new ApolloLink((operation, forward) => {
- const token = '' // store.state.token
+
+ const token = store.state.token
+
operation.setContext({
headers: {
Authorization: token && token.length > 0 ? `Bearer ${token}` : '',
@@ -52,6 +57,7 @@ const apolloProvider = new VueApollo({
})
Vue.use(BootstrapVue)
+
Vue.use(IconsPlugin)
Vue.use(moment)
diff --git a/admin/src/store/store.js b/admin/src/store/store.js
index 1dba6b9e3..38a210fe1 100644
--- a/admin/src/store/store.js
+++ b/admin/src/store/store.js
@@ -14,6 +14,9 @@ export const mutations = {
resetOpenCreations: (state) => {
state.openCreations = 0
},
+ token: (state, token) => {
+ state.token = token
+ },
}
const store = new Vuex.Store({
diff --git a/admin/src/store/store.test.js b/admin/src/store/store.test.js
new file mode 100644
index 000000000..9ab9d980b
--- /dev/null
+++ b/admin/src/store/store.test.js
@@ -0,0 +1,15 @@
+import { mutations } from './store'
+
+const { token } = mutations
+
+describe('Vuex store', () => {
+ describe('mutations', () => {
+ describe('token', () => {
+ it('sets the state of token', () => {
+ const state = { token: null }
+ token(state, '1234')
+ expect(state.token).toEqual('1234')
+ })
+ })
+ })
+})
diff --git a/admin/test/testSetup.js b/admin/test/testSetup.js
index 118c0b1ce..3b6b50218 100644
--- a/admin/test/testSetup.js
+++ b/admin/test/testSetup.js
@@ -2,6 +2,9 @@ import { createLocalVue } from '@vue/test-utils'
import Vue from 'vue'
import { BootstrapVue } from 'bootstrap-vue'
+// without this async calls are not working
+import 'regenerator-runtime'
+
global.localVue = createLocalVue()
global.localVue.use(BootstrapVue)
diff --git a/admin/yarn.lock b/admin/yarn.lock
index 0c8f9965e..d7960320b 100644
--- a/admin/yarn.lock
+++ b/admin/yarn.lock
@@ -10623,7 +10623,7 @@ regenerator-runtime@^0.11.0:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
-regenerator-runtime@^0.13.4:
+regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9:
version "0.13.9"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts
index f21082d1d..7a55de8e8 100644
--- a/backend/src/config/index.ts
+++ b/backend/src/config/index.ts
@@ -51,7 +51,6 @@ const email = {
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/vue/checkEmail/$1',
}
diff --git a/backend/src/graphql/directive/isAuthorized.ts b/backend/src/graphql/directive/isAuthorized.ts
index d72f19456..6245ef8ba 100644
--- a/backend/src/graphql/directive/isAuthorized.ts
+++ b/backend/src/graphql/directive/isAuthorized.ts
@@ -2,9 +2,6 @@
import { AuthChecker } from 'type-graphql'
-import CONFIG from '../../config'
-import { apiGet } from '../../apis/HttpRequest'
-
import decode from '../../jwt/decode'
import encode from '../../jwt/encode'
@@ -13,7 +10,7 @@ const isAuthorized: AuthChecker = async (
) => {
if (context.token) {
const decoded = decode(context.token)
- context.pubKey = decoded.pubKey
+ context.pubKey = Buffer.from(decoded.pubKey).toString('hex')
context.setHeaders.push({ key: 'token', value: encode(decoded.pubKey) })
return true
}
diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts
index 08651ae17..5b7682e01 100644
--- a/backend/src/graphql/model/User.ts
+++ b/backend/src/graphql/model/User.ts
@@ -10,15 +10,17 @@ export class User {
@PrimaryGeneratedColumn()
id: number
*/
- constructor(json: any) {
- this.email = json.email
- this.firstName = json.first_name
- this.lastName = json.last_name
- this.username = json.username
- this.description = json.description
- this.pubkey = json.public_hex
- this.language = json.language
- this.publisherId = json.publisher_id
+ constructor(json?: any) {
+ if (json) {
+ this.email = json.email
+ this.firstName = json.first_name
+ this.lastName = json.last_name
+ this.username = json.username
+ this.description = json.description
+ this.pubkey = json.public_hex
+ this.language = json.language
+ this.publisherId = json.publisher_id
+ }
}
@Field(() => String)
diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts
index 968ce9d4c..ae9e318ae 100644
--- a/backend/src/graphql/resolver/TransactionResolver.ts
+++ b/backend/src/graphql/resolver/TransactionResolver.ts
@@ -613,9 +613,6 @@ export class TransactionResolver {
await queryRunner.commitTransaction()
} catch (e) {
await queryRunner.rollbackTransaction()
- throw e
- } finally {
- await queryRunner.release()
// TODO: This is broken code - we should never correct an autoincrement index in production
// according to dario it is required tho to properly work. The index of the table is used as
// index for the transaction which requires a chain without gaps
@@ -627,6 +624,9 @@ export class TransactionResolver {
// eslint-disable-next-line no-console
console.log('problems with reset auto increment: %o', error)
})
+ throw e
+ } finally {
+ await queryRunner.release()
}
// send notification email
// TODO: translate
diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts
index 5c4625938..25f83bb09 100644
--- a/backend/src/graphql/resolver/UserResolver.ts
+++ b/backend/src/graphql/resolver/UserResolver.ts
@@ -22,14 +22,14 @@ import {
} from '../../middleware/klicktippMiddleware'
import { CheckEmailResponse } from '../model/CheckEmailResponse'
import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository'
+import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
import { Setting } from '../enum/Setting'
import { UserRepository } from '../../typeorm/repository/User'
import { LoginUser } from '@entity/LoginUser'
-import { LoginElopageBuys } from '@entity/LoginElopageBuys'
import { LoginUserBackup } from '@entity/LoginUserBackup'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { sendEMail } from '../../util/sendEMail'
-import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
+import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sodium = require('sodium-native')
@@ -201,33 +201,32 @@ export class UserResolver {
@Ctx() context: any,
): Promise {
email = email.trim().toLowerCase()
- const result = await apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', { email, password })
-
- // if there is no user, throw an authentication error
- if (!result.success) {
- throw new Error(result.data)
- }
-
- context.setHeaders.push({
- key: 'token',
- value: encode(result.data.user.public_hex),
+ // const result = await apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', { email, password })
+ // UnsecureLogin
+ const loginUserRepository = getCustomRepository(LoginUserRepository)
+ const loginUser = await loginUserRepository.findByEmail(email).catch(() => {
+ throw new Error('No user with this credentials')
})
- const user = new User(result.data.user)
- // Hack: Database Field is not validated properly and not nullable
- if (user.publisherId === 0) {
- user.publisherId = undefined
+ const passwordHash = SecretKeyCryptographyCreateKey(email, password) // return short and long hash
+ const loginUserPassword = BigInt(loginUser.password.toString())
+ if (loginUserPassword !== passwordHash[0].readBigUInt64LE()) {
+ throw new Error('No user with this credentials')
}
- user.hasElopage = result.data.hasElopage
- // read additional settings from settings table
+ // TODO: If user has no pubKey Create it again and update user.
+
const userRepository = getCustomRepository(UserRepository)
let userEntity: void | DbUser
- userEntity = await userRepository.findByPubkeyHex(user.pubkey).catch(() => {
+ const loginUserPubKey = loginUser.pubKey
+ const loginUserPubKeyString = loginUserPubKey.toString('hex')
+ userEntity = await userRepository.findByPubkeyHex(loginUserPubKeyString).catch(() => {
+ // User not stored in state_users
+ // TODO: Check with production data - email is unique which can cause problems
userEntity = new DbUser()
- userEntity.firstName = user.firstName
- userEntity.lastName = user.lastName
- userEntity.username = user.username
- userEntity.email = user.email
- userEntity.pubkey = Buffer.from(user.pubkey, 'hex')
+ userEntity.firstName = loginUser.firstName
+ userEntity.lastName = loginUser.lastName
+ userEntity.username = loginUser.username
+ userEntity.email = loginUser.email
+ userEntity.pubkey = loginUser.pubKey
userRepository.save(userEntity).catch(() => {
throw new Error('error by save userEntity')
@@ -237,16 +236,28 @@ export class UserResolver {
throw new Error('error with cannot happen')
}
- // Save publisherId if Elopage is not yet registered
+ const user = new User()
+ user.email = email
+ user.firstName = loginUser.firstName
+ user.lastName = loginUser.lastName
+ user.username = loginUser.username
+ user.description = loginUser.description
+ user.pubkey = loginUserPubKeyString
+ user.language = loginUser.language
+
+ // Elopage Status & Stored PublisherId
+ user.hasElopage = await this.hasElopage({ pubKey: loginUserPubKeyString })
if (!user.hasElopage && publisherId) {
user.publisherId = publisherId
-
+ // TODO: Check if we can use updateUserInfos
+ // await this.updateUserInfos({ publisherId }, { pubKey: loginUser.pubKey })
const loginUserRepository = getCustomRepository(LoginUserRepository)
const loginUser = await loginUserRepository.findOneOrFail({ email: userEntity.email })
loginUser.publisherId = publisherId
loginUserRepository.save(loginUser)
}
+ // coinAnimation
const userSettingRepository = getCustomRepository(UserSettingRepository)
const coinanimation = await userSettingRepository
.readBoolean(userEntity.id, Setting.COIN_ANIMATION)
@@ -254,6 +265,12 @@ export class UserResolver {
throw new Error(error)
})
user.coinanimation = coinanimation
+
+ context.setHeaders.push({
+ key: 'token',
+ value: encode(loginUser.pubKey),
+ })
+
return user
}
@@ -537,7 +554,7 @@ export class UserResolver {
await queryRunner.startTransaction('READ UNCOMMITTED')
try {
- if (coinanimation) {
+ if (coinanimation !== null && coinanimation !== undefined) {
queryRunner.manager
.getCustomRepository(UserSettingRepository)
.setOrUpdate(userEntity.id, Setting.COIN_ANIMATION, coinanimation.toString())
@@ -609,7 +626,8 @@ export class UserResolver {
return false
}
- const elopageBuyCount = await LoginElopageBuys.count({ payerEmail: userEntity.email })
+ const loginElopageBuysRepository = getCustomRepository(LoginElopageBuysRepository)
+ const elopageBuyCount = await loginElopageBuysRepository.count({ payerEmail: userEntity.email })
return elopageBuyCount > 0
}
}
diff --git a/backend/src/typeorm/repository/LoginElopageBuys.ts b/backend/src/typeorm/repository/LoginElopageBuys.ts
new file mode 100644
index 000000000..15f2a8492
--- /dev/null
+++ b/backend/src/typeorm/repository/LoginElopageBuys.ts
@@ -0,0 +1,5 @@
+import { EntityRepository, Repository } from 'typeorm'
+import { LoginElopageBuys } from '@entity/LoginElopageBuys'
+
+@EntityRepository(LoginElopageBuys)
+export class LoginElopageBuysRepository extends Repository {}
diff --git a/backend/src/typeorm/repository/LoginUser.ts b/backend/src/typeorm/repository/LoginUser.ts
index d0db007d0..65ac6f67b 100644
--- a/backend/src/typeorm/repository/LoginUser.ts
+++ b/backend/src/typeorm/repository/LoginUser.ts
@@ -2,4 +2,10 @@ import { EntityRepository, Repository } from 'typeorm'
import { LoginUser } from '@entity/LoginUser'
@EntityRepository(LoginUser)
-export class LoginUserRepository extends Repository {}
+export class LoginUserRepository extends Repository {
+ async findByEmail(email: string): Promise {
+ return this.createQueryBuilder('loginUser')
+ .where('loginUser.email = :email', { email })
+ .getOneOrFail()
+ }
+}
diff --git a/backend/src/typeorm/repository/User.ts b/backend/src/typeorm/repository/User.ts
index 441c1b2c8..e127c179c 100644
--- a/backend/src/typeorm/repository/User.ts
+++ b/backend/src/typeorm/repository/User.ts
@@ -9,6 +9,15 @@ export class UserRepository extends Repository {
.getOneOrFail()
}
+ async findByPubkeyHexBuffer(pubkeyHexBuffer: Buffer): Promise {
+ const pubKeyString = pubkeyHexBuffer.toString('hex')
+ return await this.findByPubkeyHex(pubKeyString)
+ }
+
+ async findByEmail(email: string): Promise {
+ return this.createQueryBuilder('user').where('user.email = :email', { email }).getOneOrFail()
+ }
+
async getUsersIndiced(userIds: number[]): Promise {
if (!userIds.length) return []
const users = await this.createQueryBuilder('user')
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index bd23b43b3..9f3d3d618 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -1,170 +1,166 @@
-version: "3.4"
-
-services:
- ########################################################
- # FRONTEND #############################################
- ########################################################
- frontend:
- image: gradido/frontend:development
- build:
- target: development
- networks:
- - external-net
- environment:
- - NODE_ENV="development"
- # - DEBUG=true
- volumes:
- # This makes sure the docker container has its own node modules.
- # Therefore it is possible to have a different node version on the host machine
- - frontend_node_modules:/app/node_modules
- # bind the local folder to the docker to allow live reload
- - ./frontend:/app
-
- ########################################################
- # ADMIN INTERFACE ######################################
- ########################################################
- admin:
- image: gradido/admin:development
- build:
- target: development
- networks:
- - external-net
- environment:
- - NODE_ENV="development"
- # - DEBUG=true
- volumes:
- # This makes sure the docker container has its own node modules.
- # Therefore it is possible to have a different node version on the host machine
- - admin_node_modules:/app/node_modules
- # bind the local folder to the docker to allow live reload
- - ./admin:/app
-
- ########################################################
- # BACKEND ##############################################
- ########################################################
- backend:
- image: gradido/backend:development
- build:
- target: development
- networks:
- - external-net
- - internal-net
- environment:
- - NODE_ENV="development"
- volumes:
- # This makes sure the docker container has its own node modules.
- # Therefore it is possible to have a different node version on the host machine
- - backend_node_modules:/app/node_modules
- - backend_database_node_modules:/database/node_modules
- - backend_database_build:/database/build
- # bind the local folder to the docker to allow live reload
- - ./backend:/app
- - ./database:/database
-
- ########################################################
- # DATABASE ##############################################
- ########################################################
- database:
- # we always run on production here since else the service lingers
- # feel free to change this behaviour if it seems useful
- # Due to problems with the volume caching the built files
- # we changed this to test build. This keeps the service running.
- image: gradido/database:test_up
- build:
- target: test_up
- #networks:
- # - external-net
- # - internal-net
- environment:
- - NODE_ENV="development"
- volumes:
- # This makes sure the docker container has its own node modules.
- # Therefore it is possible to have a different node version on the host machine
- - database_node_modules:/app/node_modules
- - database_build:/app/build
- # bind the local folder to the docker to allow live reload
- - ./database:/app
-
- #########################################################
- ## LOGIN SERVER #########################################
- #########################################################
- login-server:
- build:
- dockerfile: Dockerfiles/ubuntu/Dockerfile.debug
- networks:
- - external-net
- - internal-net
- security_opt:
- - seccomp:unconfined
- cap_add:
- - SYS_PTRACE
- volumes:
- - ./logs:/var/log/grd_login
- - ./login_server/src:/code/src
- - ./login_server/dependencies:/code/dependencies
- - ./login_server/scripts:/code/scripts
- - ./configs/login_server:/etc/grd_login
- - login_build_ubuntu_3.1:/code/build
-
-
- #########################################################
- ## COMMUNITY SERVER (cakephp with php-fpm) ##############
- #########################################################
- community-server:
- build:
- context: .
- target: community_server
- dockerfile: ./community_server/Dockerfile
- depends_on:
- - mariadb
- networks:
- - internal-net
- - external-net
- volumes:
- - ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
- - ./community_server/src:/var/www/cakephp/src
-
- #########################################################
- ## MARIADB ##############################################
- #########################################################
- mariadb:
- networks:
- - internal-net
- - external-net
-
- #########################################################
- ## NGINX ################################################
- #########################################################
- nginx:
- depends_on:
- - frontend
- - community-server
- - login-server
- volumes:
- - ./logs/nginx:/var/log/nginx
-
- #########################################################
- ## PHPMYADMIN ###########################################
- #########################################################
- phpmyadmin:
- image: phpmyadmin
- environment:
- - PMA_ARBITRARY=1
- #restart: always
- ports:
- - 8074:80
- networks:
- - internal-net
- - external-net
- volumes:
- - /sessions
-
-volumes:
- frontend_node_modules:
- admin_node_modules:
- backend_node_modules:
- backend_database_node_modules:
- backend_database_build:
- database_node_modules:
- database_build:
+version: "3.4"
+
+services:
+ ########################################################
+ # FRONTEND #############################################
+ ########################################################
+ frontend:
+ image: gradido/frontend:development
+ build:
+ target: development
+ environment:
+ - NODE_ENV="development"
+ # - DEBUG=true
+ volumes:
+ # This makes sure the docker container has its own node modules.
+ # Therefore it is possible to have a different node version on the host machine
+ - frontend_node_modules:/app/node_modules
+ # bind the local folder to the docker to allow live reload
+ - ./frontend:/app
+
+ ########################################################
+ # ADMIN INTERFACE ######################################
+ ########################################################
+ admin:
+ image: gradido/admin:development
+ build:
+ target: development
+ environment:
+ - NODE_ENV="development"
+ # - DEBUG=true
+ volumes:
+ # This makes sure the docker container has its own node modules.
+ # Therefore it is possible to have a different node version on the host machine
+ - admin_node_modules:/app/node_modules
+ # bind the local folder to the docker to allow live reload
+ - ./admin:/app
+
+ ########################################################
+ # BACKEND ##############################################
+ ########################################################
+ backend:
+ image: gradido/backend:development
+ build:
+ target: development
+ networks:
+ - external-net
+ - internal-net
+ environment:
+ - NODE_ENV="development"
+ volumes:
+ # This makes sure the docker container has its own node modules.
+ # Therefore it is possible to have a different node version on the host machine
+ - backend_node_modules:/app/node_modules
+ - backend_database_node_modules:/database/node_modules
+ - backend_database_build:/database/build
+ # bind the local folder to the docker to allow live reload
+ - ./backend:/app
+ - ./database:/database
+
+ ########################################################
+ # DATABASE ##############################################
+ ########################################################
+ database:
+ # we always run on production here since else the service lingers
+ # feel free to change this behaviour if it seems useful
+ # Due to problems with the volume caching the built files
+ # we changed this to test build. This keeps the service running.
+ image: gradido/database:test_up
+ build:
+ target: test_up
+ #networks:
+ # - external-net
+ # - internal-net
+ environment:
+ - NODE_ENV="development"
+ volumes:
+ # This makes sure the docker container has its own node modules.
+ # Therefore it is possible to have a different node version on the host machine
+ - database_node_modules:/app/node_modules
+ - database_build:/app/build
+ # bind the local folder to the docker to allow live reload
+ - ./database:/app
+
+ #########################################################
+ ## LOGIN SERVER #########################################
+ #########################################################
+ login-server:
+ build:
+ dockerfile: Dockerfiles/ubuntu/Dockerfile.debug
+ networks:
+ - external-net
+ - internal-net
+ security_opt:
+ - seccomp:unconfined
+ cap_add:
+ - SYS_PTRACE
+ volumes:
+ - ./logs:/var/log/grd_login
+ - ./login_server/src:/code/src
+ - ./login_server/dependencies:/code/dependencies
+ - ./login_server/scripts:/code/scripts
+ - ./configs/login_server:/etc/grd_login
+ - login_build_ubuntu_3.1:/code/build
+
+
+ #########################################################
+ ## COMMUNITY SERVER (cakephp with php-fpm) ##############
+ #########################################################
+ community-server:
+ build:
+ context: .
+ target: community_server
+ dockerfile: ./community_server/Dockerfile
+ depends_on:
+ - mariadb
+ networks:
+ - internal-net
+ - external-net
+ volumes:
+ - ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
+ - ./community_server/src:/var/www/cakephp/src
+
+ #########################################################
+ ## MARIADB ##############################################
+ #########################################################
+ mariadb:
+ networks:
+ - internal-net
+ - external-net
+
+ #########################################################
+ ## NGINX ################################################
+ #########################################################
+ nginx:
+ depends_on:
+ - frontend
+ - community-server
+ - login-server
+ volumes:
+ - ./logs/nginx:/var/log/nginx
+
+ #########################################################
+ ## PHPMYADMIN ###########################################
+ #########################################################
+ phpmyadmin:
+ image: phpmyadmin
+ environment:
+ - PMA_ARBITRARY=1
+ #restart: always
+ ports:
+ - 8074:80
+ networks:
+ - internal-net
+ - external-net
+ volumes:
+ - /sessions
+
+volumes:
+ frontend_node_modules:
+ admin_node_modules:
+ backend_node_modules:
+ backend_database_node_modules:
+ backend_database_build:
+ database_node_modules:
+ database_build:
login_build_ubuntu_3.1:
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index b212c6f21..9352fd162 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,6 +15,7 @@ services:
context: ./frontend
target: production
networks:
+ - external-net
- internal-net
ports:
- 3000:3000
@@ -39,6 +40,7 @@ services:
context: ./admin
target: production
networks:
+ - external-net
- internal-net
ports:
- 8080:8080
diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json
index 0dd3ba926..faa61886d 100644
--- a/frontend/src/locales/de.json
+++ b/frontend/src/locales/de.json
@@ -46,6 +46,7 @@
"change-password": "Fehler beim Ändern des Passworts",
"error": "Fehler",
"no-account": "Leider konnten wir keinen Account finden mit diesen Daten!",
+ "no-email-verify": "Die Email wurde noch nicht bestätigt, bitte überprüfe deine Emails und klicke auf den Aktivierungslink!",
"session-expired": "Sitzung abgelaufen!"
},
"form": {
@@ -180,9 +181,12 @@
"uppercase": "Ein Großbuchstabe erforderlich."
},
"thx": {
+ "activateEmail": "Deine Email wurde noch nicht aktiviert, bitte überprüfe deine Email und Klicke den Aktivierungslink!",
"checkEmail": "Deine Email würde erfolgreich verifiziert.",
"email": "Wir haben dir eine eMail gesendet.",
- "register": "Du bist jetzt registriert.",
+ "emailActivated": "Danke dass Du deine Email bestätigt hast.",
+ "errorTitle": "Achtung!",
+ "register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.",
"title": "Danke!"
}
diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json
index 99fcd46a7..91e25f61d 100644
--- a/frontend/src/locales/en.json
+++ b/frontend/src/locales/en.json
@@ -46,6 +46,7 @@
"change-password": "Error while changing password",
"error": "Error",
"no-account": "Unfortunately we could not find an account to the given data!",
+ "no-email-verify": "Your email is not activated yet, please check your emails and click the activation link!",
"session-expired": "The session expired"
},
"form": {
@@ -180,9 +181,12 @@
"uppercase": "One uppercase letter required."
},
"thx": {
+ "activateEmail": "Your email has not been activated yet, please check your emails and click the activation link!",
"checkEmail": "Your email has been successfully verified.",
"email": "We have sent you an email.",
- "register": "You are registred now.",
+ "emailActivated": "Thank you your email has been activated.",
+ "errorTitle": "Attention!",
+ "register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.",
"title": "Thank you!"
}
diff --git a/frontend/src/routes/routes.js b/frontend/src/routes/routes.js
index f4f0dfe04..a3c1389ce 100755
--- a/frontend/src/routes/routes.js
+++ b/frontend/src/routes/routes.js
@@ -47,7 +47,7 @@ const routes = [
path: '/thx/:comingFrom',
component: () => import('../views/Pages/thx.vue'),
beforeEnter: (to, from, next) => {
- const validFrom = ['password', 'reset', 'register']
+ const validFrom = ['password', 'reset', 'register', 'login']
if (!validFrom.includes(from.path.split('/')[1])) {
next({ path: '/login' })
} else {
diff --git a/frontend/src/views/Pages/Login.vue b/frontend/src/views/Pages/Login.vue
index de1ae993a..45e700099 100755
--- a/frontend/src/views/Pages/Login.vue
+++ b/frontend/src/views/Pages/Login.vue
@@ -104,9 +104,14 @@ export default {
this.$router.push('/overview')
loader.hide()
})
- .catch(() => {
+ .catch((error) => {
+ if (!error.message.includes('user email not validated')) {
+ this.$toasted.error(this.$t('error.no-account'))
+ } else {
+ // : this.$t('error.no-email-verify')
+ this.$router.push('/thx/login')
+ }
loader.hide()
- this.$toasted.error(this.$t('error.no-account'))
})
},
},
diff --git a/frontend/src/views/Pages/Register.vue b/frontend/src/views/Pages/Register.vue
index 00114eb04..ea4000cff 100755
--- a/frontend/src/views/Pages/Register.vue
+++ b/frontend/src/views/Pages/Register.vue
@@ -161,6 +161,7 @@ import InputEmail from '../../components/Inputs/InputEmail.vue'
import InputPasswordConfirmation from '../../components/Inputs/InputPasswordConfirmation.vue'
import LanguageSwitchSelect from '../../components/LanguageSwitchSelect.vue'
import { registerUser } from '../../graphql/mutations'
+import { localeChanged } from 'vee-validate'
import { getCommunityInfoMixin } from '../../mixins/getCommunityInfo'
export default {
@@ -189,6 +190,9 @@ export default {
methods: {
updateLanguage(e) {
this.language = e
+ this.$store.commit('language', this.language)
+ this.$i18n.locale = this.language
+ localeChanged(this.language)
},
getValidationState({ dirty, validated, valid = null }) {
return dirty || validated ? valid : null
diff --git a/frontend/src/views/Pages/thx.vue b/frontend/src/views/Pages/thx.vue
index 9d9143456..5884cc61c 100644
--- a/frontend/src/views/Pages/thx.vue
+++ b/frontend/src/views/Pages/thx.vue
@@ -4,10 +4,12 @@
@@ -17,25 +19,33 @@