This commit is contained in:
Einhornimmond 2021-10-05 12:05:23 +02:00
parent 41afaa0e01
commit e49230e1ea
10 changed files with 132 additions and 82 deletions

View File

@ -73,7 +73,7 @@ export class TransactionResolver {
}
const recipiantPublicKey = await getPublicKey(email, context.sessionId)
if(!recipiantPublicKey) {
if (!recipiantPublicKey) {
throw new Error('recipiant not known')
}

View File

@ -8,7 +8,9 @@ import { LoginViaVerificationCode } from '../models/LoginViaVerificationCode'
import { SendPasswordResetEmailResponse } from '../models/SendPasswordResetEmailResponse'
import { UpdateUserInfosResponse } from '../models/UpdateUserInfosResponse'
import { User } from '../models/User'
import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository'
import encode from '../../jwt/encode'
import { Setting } from '../../types'
import {
ChangePasswordArgs,
CheckUsernameArgs,
@ -22,6 +24,7 @@ import {
klicktippNewsletterStateMiddleware,
} from '../../middleware/klicktippMiddleware'
import { CheckEmailResponse } from '../models/CheckEmailResponse'
import { getCustomRepository } from 'typeorm'
@Resolver()
export class UserResolver {
@Query(() => User)
@ -154,7 +157,7 @@ export class UserResolver {
}
const result = await apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
if (!result.success) throw new Error(result.data)
return new UpdateUserInfosResponse(result.data)
return new UpdateUserInfosResponse(result.data)
}
@Query(() => CheckUsernameResponse)

View File

@ -1,6 +1 @@
export default function createTransaction()
{
}
export default function createTransaction() {}

View File

@ -4,29 +4,31 @@ import { isHexPublicKey } from '../../util/validate'
// target can be email, username or public_key
// groupId if not null and another community, try to get public key from there
export default async function getPublicKey(target: string, sessionId:number, groupId: number = 0): Promise<string | undefined>
{
// if it is already a public key, return it
if(isHexPublicKey(target)) {
return target
export default async function getPublicKey(
target: string,
sessionId: number,
groupId = 0,
): Promise<string | undefined> {
// if it is already a public key, return it
if (isHexPublicKey(target)) {
return target
}
// assume it is a email address if it's contain a @
if (/@/i.test(target)) {
const result = await apiPost(CONFIG.LOGIN_API_URL + 'getUserInfos', {
session_id: sessionId,
email: target,
ask: ['user.pubkeyhex'],
})
if (result.success) {
return result.data.userData.pubkeyhex
}
}
// assume it is a email address if it's contain a @
if(/@/i.test(target)) {
const result = await apiPost(CONFIG.LOGIN_API_URL + 'getUserInfos', {
session_id: sessionId,
email: target,
ask: ['user.pubkeyhex']
})
if (result.success) {
return result.data.userData.pubkeyhex
}
}
// if username is used add code here
// if username is used add code here
// if we have multiple communities add code here
// if we have multiple communities add code here
return undefined
}
return undefined
}

View File

@ -3,51 +3,50 @@ import { from_hex } from 'libsodium-wrappers'
import { isHexPublicKey, hasUserAmount } from '../../util/validate'
import { User as dbUser } from '../../typeorm/entity/User'
/**
*
*
* @param senderPublicKey as hex string
* @param recipiantPublicKey as hex string
* @param amount as float
* @param memo
* @param groupId
* @param amount as float
* @param memo
* @param groupId
*/
export default async function sendCoins(
senderUser: dbUser,
recipiantPublicKey:string,
amount:number,
memo:string,
groupId:number = 0)
{
if(senderUser.pubkey.length != 32) {
throw new Error('invalid sender public key')
}
if(!isHexPublicKey(recipiantPublicKey)) {
throw new Error('invalid recipiant public key')
}
if(amount <= 0) {
throw new Error('invalid amount')
}
if(!hasUserAmount(senderUser, amount)) {
throw new Error('user hasn\'t enough GDD')
}
const protoRoot = await protobuf.load('../../proto/gradido/GradidoTransfer.proto')
const GradidoTransfer = protoRoot.lookupType('proto.gradido.GradidoTransfer')
const TransferAmount = protoRoot.lookupType('proto.gradido.TransferAmount')
senderUser: dbUser,
recipiantPublicKey: string,
amount: number,
memo: string,
groupId = 0,
) {
if (senderUser.pubkey.length != 32) {
throw new Error('invalid sender public key')
}
if (!isHexPublicKey(recipiantPublicKey)) {
throw new Error('invalid recipiant public key')
}
if (amount <= 0) {
throw new Error('invalid amount')
}
if (!hasUserAmount(senderUser, amount)) {
throw new Error("user hasn't enough GDD")
}
const protoRoot = await protobuf.load('../../proto/gradido/GradidoTransfer.proto')
const transferAmount = TransferAmount.create({
pubkey: senderUser.pubkey,
amount: amount / 10000
const GradidoTransfer = protoRoot.lookupType('proto.gradido.GradidoTransfer')
const TransferAmount = protoRoot.lookupType('proto.gradido.TransferAmount')
const transferAmount = TransferAmount.create({
pubkey: senderUser.pubkey,
amount: amount / 10000,
})
// no group id is given so we assume it is a local transfer
if (!groupId) {
const LocalTransfer = protoRoot.lookupType('proto.gradido.LocalTransfer')
const localTransfer = LocalTransfer.create({
sender: transferAmount,
recipiant: from_hex(recipiantPublicKey),
})
// no group id is given so we assume it is a local transfer
if(!groupId) {
const LocalTransfer = protoRoot.lookupType('proto.gradido.LocalTransfer')
const localTransfer = LocalTransfer.create({
sender: transferAmount,
recipiant: from_hex(recipiantPublicKey)
})
return GradidoTransfer.create({local: localTransfer})
}
}
return GradidoTransfer.create({ local: localTransfer })
}
}

View File

@ -1,4 +1,5 @@
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
import { UserSetting } from './UserSetting'
// import { Group } from "./Group"
@Entity('state_users')
@ -27,6 +28,9 @@ export class User extends BaseEntity {
@Column()
disabled: boolean
@OneToMany(() => UserSetting, (userSetting) => userSetting.user)
settings: UserSetting[]
static findByPubkeyHex(pubkeyHex: string): Promise<User> {
return this.createQueryBuilder('user')
.where('hex(user.pubkey) = :pubkeyHex', { pubkeyHex })

View File

@ -4,18 +4,18 @@ import { getRepository } from 'typeorm'
import { calculateDecay } from './decay'
import { UserResolver } from '../graphql/resolvers'
function isHexPublicKey(publicKey:string): boolean {
return /^[0-9A-Fa-f]{64}$/i.test(publicKey)
function isHexPublicKey(publicKey: string): boolean {
return /^[0-9A-Fa-f]{64}$/i.test(publicKey)
}
async function hasUserAmount(user:dbUser, amount:number): Promise<boolean> {
if(amount < 0) return false
const balanceRepository = getRepository(dbBalance)
const balance = await balanceRepository.findOne({ userId: user.id })
if(!balance) return false
async function hasUserAmount(user: dbUser, amount: number): Promise<boolean> {
if (amount < 0) return false
const balanceRepository = getRepository(dbBalance)
const balance = await balanceRepository.findOne({ userId: user.id })
if (!balance) return false
const decay = await calculateDecay(balance.amount, balance.recordDate, new Date())
return decay > amount
const decay = await calculateDecay(balance.amount, balance.recordDate, new Date())
return decay > amount
}
export { isHexPublicKey, hasUserAmount }
export { isHexPublicKey, hasUserAmount }

View File

@ -2,7 +2,7 @@
# yarn lockfile v1
"@apollo/protobufjs@1.2.2":
"@apollo/protobufjs@1.2.2", "@apollo/protobufjs@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c"
integrity sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==
@ -336,6 +336,11 @@
"@types/koa-compose" "*"
"@types/node" "*"
"@types/libsodium-wrappers@^0.7.9":
version "0.7.9"
resolved "https://registry.yarnpkg.com/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#89c3ad2156d5143e64bce86cfeb0045a983aeccc"
integrity sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw==
"@types/long@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
@ -2339,6 +2344,18 @@ libphonenumber-js@^1.9.7:
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.22.tgz#b6b460603dedbd58f2d71f15500f216d70850fad"
integrity sha512-nE0aF0wrNq09ewF36s9FVqRW73hmpw6cobVDlbexmsu1432LEfuN24BCudNuRx4t2rElSeK/N0JbedzRW/TC4A==
libsodium-wrappers@^0.7.9:
version "0.7.9"
resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#4ffc2b69b8f7c7c7c5594a93a4803f80f6d0f346"
integrity sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ==
dependencies:
libsodium "^0.7.0"
libsodium@^0.7.0:
version "0.7.9"
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b"
integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A==
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"

View File

@ -0,0 +1,28 @@
/* FIRST MIGRATION
*
* This migration is special since it takes into account that
* the database can be setup already but also may not be.
* Therefore you will find all `CREATE TABLE` statements with
* a `IF NOT EXISTS`, all `INSERT` with an `IGNORE` and in the
* downgrade function all `DROP TABLE` with a `IF EXISTS`.
* This ensures compatibility for existing or non-existing
* databases.
*/
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(`
CREATE TABLE IF NOT EXISTS userSetting (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
userId int(11) NOT NULL,
key varchar(255) NOT NULL,
value varchar(255) NOT NULL
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
// write downgrade logic as parameter of queryFn
await queryFn(`DROP TABLE IF EXISTS userSettings;`)
}

View File

@ -28,6 +28,7 @@ export const updateUserInfos = gql`
$password: String
$passwordNew: String
$locale: String
$coinanimation: Boolean
) {
updateUserInfos(
email: $email
@ -38,6 +39,7 @@ export const updateUserInfos = gql`
password: $password
passwordNew: $passwordNew
language: $locale
coinanimation: $coinanimation
) {
validValues
}