mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
refactor: Provide pubKey in context to avoid API calls
This commit is contained in:
parent
9211f52d7f
commit
d86a3dee42
@ -15,7 +15,8 @@ export const isAuthorized: AuthChecker<any> = async ({ root, args, context, info
|
||||
`${CONFIG.LOGIN_API_URL}checkSessionState?session_id=${decoded.sessionId}`,
|
||||
)
|
||||
context.sessionId = decoded.sessionId
|
||||
context.setHeaders.push({ key: 'token', value: encode(decoded.sessionId) })
|
||||
context.pubKey = decoded.pubKey
|
||||
context.setHeaders.push({ key: 'token', value: encode(decoded.sessionId, decoded.pubKey) })
|
||||
return result.success
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,7 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { Resolver, Query, Ctx, Authorized } from 'type-graphql'
|
||||
import CONFIG from '../../config'
|
||||
import { Balance } from '../models/Balance'
|
||||
import { apiGet } from '../../apis/HttpRequest'
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { Balance as dbBalance } from '../../typeorm/entity/Balance'
|
||||
import calculateDecay from '../../util/decay'
|
||||
@ -15,20 +13,14 @@ export class BalanceResolver {
|
||||
@Authorized()
|
||||
@Query(() => Balance)
|
||||
async balance(@Ctx() context: any): Promise<Balance> {
|
||||
// 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 userEntity = await dbUser.findByPubkeyHex(context.pubKey)
|
||||
const balanceEntity = await dbBalance.findByUser(userEntity.id)
|
||||
const now = new Date()
|
||||
const balance = new Balance({
|
||||
return new Balance({
|
||||
balance: roundFloorFrom4(balanceEntity.amount),
|
||||
decay: roundFloorFrom4(calculateDecay(balanceEntity.amount, balanceEntity.recordDate, now)),
|
||||
decay_date: now.toString(),
|
||||
})
|
||||
|
||||
return balance
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,18 +18,14 @@ export class GdtResolver {
|
||||
{ currentPage = 1, pageSize = 5, order = 'DESC' }: GdtTransactionSessionIdInput,
|
||||
@Ctx() context: any,
|
||||
): Promise<GdtEntryList> {
|
||||
// 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
|
||||
const userEntity = await dbUser.findByPubkeyHex(result.data.user.public_hex)
|
||||
const userEntity = await dbUser.findByPubkeyHex(context.pubKey)
|
||||
|
||||
const resultGDT = await apiGet(
|
||||
`${CONFIG.GDT_API_URL}/GdtEntries/listPerEmailApi/${userEntity.email}/${currentPage}/${pageSize}/${order}`,
|
||||
)
|
||||
if (!resultGDT.success) {
|
||||
throw new Error(result.data)
|
||||
throw new Error(resultGDT.data)
|
||||
}
|
||||
|
||||
return new GdtEntryList(resultGDT.data)
|
||||
|
||||
@ -22,6 +22,7 @@ import {
|
||||
klicktippNewsletterStateMiddleware,
|
||||
} from '../../middleware/klicktippMiddleware'
|
||||
import { CheckEmailResponse } from '../models/CheckEmailResponse'
|
||||
|
||||
@Resolver()
|
||||
export class UserResolver {
|
||||
@Query(() => User)
|
||||
@ -35,7 +36,10 @@ export class UserResolver {
|
||||
throw new Error(result.data)
|
||||
}
|
||||
|
||||
context.setHeaders.push({ key: 'token', value: encode(result.data.session_id) })
|
||||
context.setHeaders.push({
|
||||
key: 'token',
|
||||
value: encode(result.data.session_id, result.data.user.public_hex),
|
||||
})
|
||||
|
||||
return new User(result.data.user)
|
||||
}
|
||||
|
||||
@ -1,18 +1,26 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import jwt from 'jsonwebtoken'
|
||||
import jwt, { JwtPayload } from 'jsonwebtoken'
|
||||
import CONFIG from '../config/'
|
||||
|
||||
interface CustomJwtPayload extends JwtPayload {
|
||||
sessionId: number
|
||||
pubKey: Buffer
|
||||
}
|
||||
|
||||
export default (token: string): any => {
|
||||
if (!token) return new Error('401 Unauthorized')
|
||||
let sessionId = null
|
||||
let pubKey = null
|
||||
try {
|
||||
const decoded = jwt.verify(token, CONFIG.JWT_SECRET)
|
||||
sessionId = decoded.sub
|
||||
const decoded = <CustomJwtPayload>jwt.verify(token, CONFIG.JWT_SECRET)
|
||||
sessionId = decoded.sessionId
|
||||
pubKey = decoded.pubKey
|
||||
return {
|
||||
token,
|
||||
sessionId,
|
||||
pubKey,
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error('403.13 - Client certificate revoked')
|
||||
|
||||
@ -5,8 +5,8 @@ import jwt from 'jsonwebtoken'
|
||||
import CONFIG from '../config/'
|
||||
|
||||
// Generate an Access Token
|
||||
export default function encode(sessionId: string): string {
|
||||
const token = jwt.sign({ sessionId }, CONFIG.JWT_SECRET, {
|
||||
export default function encode(sessionId: number, pubKey: Buffer): string {
|
||||
const token = jwt.sign({ sessionId, pubKey }, CONFIG.JWT_SECRET, {
|
||||
expiresIn: CONFIG.JWT_EXPIRES_IN,
|
||||
subject: sessionId.toString(),
|
||||
})
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
const context = (args: any) => {
|
||||
const authorization = args.req.headers.authorization
|
||||
let token = null
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
const plugins = [
|
||||
{
|
||||
requestDidStart() {
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
|
||||
|
||||
// import { Group } from "./Group"
|
||||
|
||||
// Moriz: I do not like the idea of having two user tables
|
||||
@Entity('state_users')
|
||||
export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
@ -27,6 +29,9 @@ export class User extends BaseEntity {
|
||||
@Column()
|
||||
disabled: boolean
|
||||
|
||||
// Moriz: I am voting for the data mapper implementation.
|
||||
// see: https://typeorm.io/#/active-record-data-mapper/what-is-the-data-mapper-pattern
|
||||
// We should discuss this ASAP
|
||||
static findByPubkeyHex(pubkeyHex: string): Promise<User> {
|
||||
return this.createQueryBuilder('user')
|
||||
.where('hex(user.pubkey) = :pubkeyHex', { pubkeyHex })
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user