Merge branch 'master' into apollo_createTransactions_without_signation

This commit is contained in:
elweyn 2021-11-04 14:13:41 +01:00
commit 66e4d86ae0
9 changed files with 137 additions and 52 deletions

View File

@ -8,34 +8,74 @@ The Gradido model can create global prosperity and peace
The Corona crisis has fundamentally changed our world within a very short time.
The dominant financial system threatens to fail around the globe, followed by mass insolvencies, record unemployment and abject poverty. Only with a sustainable new monetary system can humanity master these challenges of the 21st century. The Gradido Academy for Bionic Economy has developed such a system.
Find out more about the Project on its [Website](https://gradido.net/). It is offering vast resources about the idea. The remaining document will discuss the gradido software only.
## Software requirements
Currently we only support `docker` as environment to run all services, since many different programming languages and frameworks are used.
Currently we only support `docker` install instructions to run all services, since many different programming languages and frameworks are used.
- [docker](https://www.docker.com/)
- [docker-compose]
### For Arch Linux
Install the required packages:
```bash
sudo pacman -S docker
sudo pacman -S docker-compose
```
Add group `docker` and then your user to it in order to allow you to run docker without sudo
```bash
sudo groupadd docker # may already exist `groupadd: group 'docker' already exists`
sudo usermod -aG docker $USER
groups # verify you have the group (requires relog)
```
Start the docker service:
```bash
sudo systemctrl start docker
```
## How to run?
1. Clone the repo and pull all submodules
### 1. Clone Sources
Clone the repo and pull all submodules
```bash
git clone git@github.com:gradido/gradido.git
git submodule update --recursive --init
```
2. Run docker compose
1. Run docker compose for the debug build
### 2. Run docker-compose
Run docker-compose to bring up the development environment
```bash
docker-compose up
```
2. Or run docker compose in production build
### Additional Build options
If you want to build for production you can do this aswell:
```bash
docker-compose -f docker-compose.yml up
```
## Services defined in this package
- [frontend](./frontend) Wallet frontend
- [backend](./backend) GraphQL & Business logic backend
- [mariadb](./mariadb) Database backend
- [login_server](./login_server) User credential storage & business logic backend
- [community_server](./community_server/) Business logic backend
We are currently restructuring the service to reduce dependencies and unify business logic into one place. Furthermore the databases defined for each service will be unified into one.
### Open the wallet
Once you have `docker-compose` up and running, you can open [http://localhost/vue](http://localhost/vue) and create yourself a new wallet account.
## Troubleshooting
| Problem | Issue | Solution | Description |
| ------- | ----- | -------- | ----------- |
| docker-compose raises database connection errors | [#1062](https://github.com/gradido/gradido/issues/1062) | End `ctrl+c` and restart the `docker-compose up` after a successful build | Several Database connection related errors occur in the docker-compose log. |
| Wallet page is empty | [#1063](https://github.com/gradido/gradido/issues/1063) | Accept Cookies and Local Storage in your Browser | The page stays empty when navigating to [http://localhost/vue](http://localhost/vue) |
## Useful Links
- [Gradido.net](https://gradido.net/)

View File

@ -4,7 +4,4 @@ import { ArgsType, Field } from 'type-graphql'
export default class CheckUsernameArgs {
@Field(() => String)
username: string
@Field(() => Number, { nullable: true })
groupId?: number
}

View File

@ -1,21 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { ObjectType, Field } from 'type-graphql'
@ObjectType()
export class CheckUsernameResponse {
constructor(json: any) {
this.state = json.state
this.msg = json.msg
this.groupId = json.group_id
}
@Field(() => String)
state: string
@Field(() => String)
msg?: string
@Field(() => Number)
groupId?: number
}

View File

@ -3,8 +3,8 @@
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
import { from_hex as fromHex } from 'libsodium-wrappers'
import { getCustomRepository } from 'typeorm'
import CONFIG from '../../config'
import { CheckUsernameResponse } from '../model/CheckUsernameResponse'
import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode'
import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse'
import { UpdateUserInfosResponse } from '../model/UpdateUserInfosResponse'
@ -22,10 +22,10 @@ import {
klicktippNewsletterStateMiddleware,
} from '../../middleware/klicktippMiddleware'
import { CheckEmailResponse } from '../model/CheckEmailResponse'
import { getCustomRepository } from 'typeorm'
import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository'
import { Setting } from '../enum/Setting'
import { UserRepository } from '../../typeorm/repository/User'
import { LoginUser } from '@entity/LoginUser'
@Resolver()
export class UserResolver {
@ -275,15 +275,27 @@ export class UserResolver {
return response
}
@Query(() => CheckUsernameResponse)
async checkUsername(
@Args() { username, groupId = 1 }: CheckUsernameArgs,
): Promise<CheckUsernameResponse> {
const response = await apiGet(
CONFIG.LOGIN_API_URL + `checkUsername?username=${username}&group_id=${groupId}`,
)
if (!response.success) throw new Error(response.data)
return new CheckUsernameResponse(response.data)
@Query(() => Boolean)
async checkUsername(@Args() { username }: CheckUsernameArgs): Promise<boolean> {
// Username empty?
if (username === '') {
throw new Error('Username must be set.')
}
// Do we fullfil the minimum character length?
const MIN_CHARACTERS_USERNAME = 2
if (username.length < MIN_CHARACTERS_USERNAME) {
throw new Error(`Username must be at minimum ${MIN_CHARACTERS_USERNAME} characters long.`)
}
const usersFound = await LoginUser.count({ username })
// Username already present?
if (usersFound !== 0) {
throw new Error(`Username "${username}" already taken.`)
}
return true
}
@Query(() => CheckEmailResponse)

View File

@ -0,0 +1,56 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
// Moriz: I do not like the idea of having two user tables
@Entity('login_users')
export class LoginUser extends BaseEntity {
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ length: 191, unique: true })
email: string
@Column({ name: 'first_name', length: 150 })
firstName: string
@Column({ name: 'last_name', length: 255, default: '' })
lastName: string
@Column({ length: 255, default: '' })
username: string
@Column({ default: '' })
description: string
@Column({ type: 'bigint', default: 0, unsigned: true })
password: string
@Column({ name: 'pubkey', type: 'binary', length: 32, default: null, nullable: true })
pubKey: Buffer
@Column({ name: 'privkey', type: 'binary', length: 80, default: null, nullable: true })
privKey: Buffer
@Column({ name: 'email_hash', type: 'binary', length: 32, default: null, nullable: true })
emailHash: Buffer
@Column({ name: 'created', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date
@Column({ name: 'email_checked', default: 0 })
emailChecked: boolean
@Column({ name: 'passphrase_shown', default: 0 })
passphraseShown: boolean
@Column({ length: 4, default: 'de' })
language: string
@Column({ default: 0 })
disabled: boolean
@Column({ name: 'group_id', default: 0, unsigned: true })
groupId: number
@Column({ name: 'publisher_id', default: 0 })
publisherId: number
}

View File

@ -0,0 +1 @@
export { LoginUser } from './0003-login_server_tables/LoginUser'

View File

@ -1,4 +1,5 @@
import { Balance } from './Balance'
import { LoginUser } from './LoginUser'
import { Migration } from './Migration'
import { Transaction } from './Transaction'
import { TransactionCreation } from './TransactionCreation'
@ -9,6 +10,7 @@ import { UserTransaction } from './UserTransaction'
export const entities = [
Balance,
LoginUser,
Migration,
Transaction,
TransactionCreation,

View File

@ -75,9 +75,7 @@ export const sendResetPasswordEmail = gql`
export const checkUsername = gql`
query($username: String!) {
checkUsername(username: $username) {
state
}
checkUsername(username: $username)
}
`

View File

@ -59,7 +59,7 @@ export const loadAllRules = (i18nCallback) => {
},
})
.then((result) => {
return result.data.checkUsername.state === 'success'
return result.data.checkUsername
})
.catch(() => {
return false