mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-01 12:44:43 +00:00
changes
This commit is contained in:
parent
41afaa0e01
commit
e49230e1ea
@ -73,7 +73,7 @@ export class TransactionResolver {
|
||||
}
|
||||
|
||||
const recipiantPublicKey = await getPublicKey(email, context.sessionId)
|
||||
if(!recipiantPublicKey) {
|
||||
if (!recipiantPublicKey) {
|
||||
throw new Error('recipiant not known')
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -1,6 +1 @@
|
||||
|
||||
|
||||
export default function createTransaction()
|
||||
{
|
||||
|
||||
}
|
||||
export default function createTransaction() {}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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"
|
||||
|
||||
28
database/migrations/0002-add_settings.ts
Normal file
28
database/migrations/0002-add_settings.ts
Normal 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;`)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user