mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
add settings as key value approach
This commit is contained in:
parent
161fae9ba2
commit
e963a34b36
@ -67,6 +67,9 @@ export class UpdateUserInfosArgs {
|
||||
|
||||
@Field({ nullable: true })
|
||||
passwordNew?: string
|
||||
|
||||
@Field({ nullable: true })
|
||||
coinanimation?: boolean
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
|
||||
@ -8,6 +8,7 @@ import { LoginViaVerificationCode } from '../models/LoginViaVerificationCode'
|
||||
import { SendPasswordResetEmailResponse } from '../models/SendPasswordResetEmailResponse'
|
||||
import { UpdateUserInfosResponse } from '../models/UpdateUserInfosResponse'
|
||||
import { User } from '../models/User'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import encode from '../../jwt/encode'
|
||||
import {
|
||||
ChangePasswordArgs,
|
||||
@ -22,6 +23,10 @@ import {
|
||||
klicktippNewsletterStateMiddleware,
|
||||
} from '../../middleware/klicktippMiddleware'
|
||||
import { CheckEmailResponse } from '../models/CheckEmailResponse'
|
||||
import { getCustomRepository } from 'typeorm'
|
||||
import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository'
|
||||
import { Setting } from '../../types'
|
||||
|
||||
@Resolver()
|
||||
export class UserResolver {
|
||||
@Query(() => User)
|
||||
@ -135,6 +140,7 @@ export class UserResolver {
|
||||
publisherId,
|
||||
password,
|
||||
passwordNew,
|
||||
coinanimation,
|
||||
}: UpdateUserInfosArgs,
|
||||
@Ctx() context: any,
|
||||
): Promise<UpdateUserInfosResponse> {
|
||||
@ -152,9 +158,47 @@ export class UserResolver {
|
||||
'User.password_old': password || undefined,
|
||||
},
|
||||
}
|
||||
const result = await apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
if (!result.success) throw new Error(result.data)
|
||||
return new UpdateUserInfosResponse(result.data)
|
||||
let response: UpdateUserInfosResponse | undefined
|
||||
if (
|
||||
firstName ||
|
||||
lastName ||
|
||||
description ||
|
||||
username ||
|
||||
language ||
|
||||
publisherId ||
|
||||
passwordNew ||
|
||||
password
|
||||
) {
|
||||
const result = await apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
|
||||
if (!result.success) throw new Error(result.data)
|
||||
response = new UpdateUserInfosResponse(result.data)
|
||||
}
|
||||
|
||||
if (coinanimation) {
|
||||
// get public key for current logged in user
|
||||
const result = await apiGet(CONFIG.LOGIN_API_URL + 'login?session_id=' + context.sessionId)
|
||||
if (!result.success) throw new Error(result.data)
|
||||
|
||||
// load user and balance
|
||||
const userEntity = await dbUser.findByPubkeyHex(result.data.user.public_hex)
|
||||
|
||||
const userSettingRepository = getCustomRepository(UserSettingRepository)
|
||||
userSettingRepository.setOrUpdate(
|
||||
userEntity.id,
|
||||
Setting.COIN_ANIMATION,
|
||||
coinanimation.toString(),
|
||||
)
|
||||
|
||||
if (!response) {
|
||||
response = new UpdateUserInfosResponse({ valid_values: 1 })
|
||||
} else {
|
||||
response.validValues++
|
||||
}
|
||||
}
|
||||
if (!response) {
|
||||
throw new Error('no valid response')
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
@Query(() => CheckUsernameResponse)
|
||||
|
||||
@ -22,7 +22,7 @@ import schema from './graphql/schema'
|
||||
// TODO implement
|
||||
// import queryComplexity, { simpleEstimator, fieldConfigEstimator } from "graphql-query-complexity";
|
||||
|
||||
const DB_VERSION = '0001-init_db'
|
||||
const DB_VERSION = '0002-add_settings'
|
||||
|
||||
async function main() {
|
||||
// open mysql connection
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToMany } 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 })
|
||||
|
||||
20
backend/src/typeorm/entity/UserSetting.ts
Normal file
20
backend/src/typeorm/entity/UserSetting.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'
|
||||
import { User } from './User'
|
||||
|
||||
@Entity()
|
||||
export class UserSetting extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column()
|
||||
userId: number
|
||||
|
||||
@ManyToOne(() => User, (user) => user.settings)
|
||||
user: User
|
||||
|
||||
@Column()
|
||||
key: string
|
||||
|
||||
@Column()
|
||||
value: string
|
||||
}
|
||||
26
backend/src/typeorm/repository/UserSettingRepository.ts
Normal file
26
backend/src/typeorm/repository/UserSettingRepository.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { UserSetting } from '../entity/UserSetting'
|
||||
import { Setting } from '../../types'
|
||||
import { isStringBoolean } from '../../util/validate'
|
||||
|
||||
@EntityRepository()
|
||||
export class UserSettingRepository extends Repository<UserSetting> {
|
||||
async setOrUpdate(userId: number, key: Setting, value: string): Promise<UserSetting> {
|
||||
switch (key) {
|
||||
case Setting.COIN_ANIMATION:
|
||||
if (!isStringBoolean(value)) {
|
||||
throw new Error("coinanimation value isn't boolean")
|
||||
}
|
||||
break
|
||||
}
|
||||
let entity = await this.findOne({ userId: userId, key: key })
|
||||
|
||||
if (!entity) {
|
||||
entity = new UserSetting()
|
||||
entity.userId = userId
|
||||
entity.key = key
|
||||
}
|
||||
entity.value = value
|
||||
return this.save(entity)
|
||||
}
|
||||
}
|
||||
5
backend/src/types.ts
Normal file
5
backend/src/types.ts
Normal file
@ -0,0 +1,5 @@
|
||||
enum Setting {
|
||||
COIN_ANIMATION = 'coinanimation',
|
||||
}
|
||||
|
||||
export { Setting }
|
||||
9
backend/src/util/validate.ts
Normal file
9
backend/src/util/validate.ts
Normal file
@ -0,0 +1,9 @@
|
||||
function isStringBoolean(value: string): boolean {
|
||||
const lowerValue = value.toLowerCase()
|
||||
if (lowerValue === 'true' || lowerValue === 'false') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export { isStringBoolean }
|
||||
1131
backend/yarn.lock
1131
backend/yarn.lock
File diff suppressed because it is too large
Load Diff
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\`;`)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user