diff --git a/backend/src/graphql/arg/RedeemJwtArgs.ts b/backend/src/graphql/arg/RedeemJwtArgs.ts deleted file mode 100644 index e9634d8ec..000000000 --- a/backend/src/graphql/arg/RedeemJwtArgs.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { MaxLength, MinLength } from 'class-validator' -import { Decimal } from 'decimal.js-light' -import { Field, ArgsType, InputType } from 'type-graphql' - -import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from '@/graphql/resolver/const/const' -import { IsPositiveDecimal } from '@/graphql/validator/Decimal' - -@InputType() -@ArgsType() -export class RedeemJwtArgs { - @Field(() => String, { nullable: false }) - gradidoID!: string - - @Field(() => String, { nullable: true }) - firstName?: string - - @Field(() => String, { nullable: true }) - alias?: string - - @Field(() => String, { nullable: false }) - communityUuid!: string - - @Field(() => String, { nullable: false }) - communityName!: string - - @Field(() => String, { nullable: false }) - code!: string - - @Field(() => Decimal, { nullable: false }) - @IsPositiveDecimal() - amount!: Decimal - - @Field(() => String, { nullable: false }) - @MaxLength(MEMO_MAX_CHARS) - @MinLength(MEMO_MIN_CHARS) - memo!: string -} diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index e51181021..7a0f65db9 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -403,8 +403,9 @@ export class TransactionLinkResolver { @Mutation(() => String) async createRedeemJwt( @Arg('gradidoID') gradidoID: string, - @Arg('communityUuid') communityUuid: string, - @Arg('communityName') communityName: string, + @Arg('senderCommunityUuid') senderCommunityUuid: string, + @Arg('senderCommunityName') senderCommunityName: string, + @Arg('receiverCommunityUuid') receiverCommunityUuid: string, @Arg('code') code: string, @Arg('amount') amount: string, @Arg('memo') memo: string, @@ -413,8 +414,9 @@ export class TransactionLinkResolver { ): Promise { logger.debug('TransactionLinkResolver.queryRedeemJwt... args=', { gradidoID, - communityUuid, - communityName, + senderCommunityUuid, + senderCommunityName, + receiverCommunityUuid, code, amount, memo, @@ -423,18 +425,20 @@ export class TransactionLinkResolver { }) const disbursementJwtPayloadType = new DisbursementJwtPayloadType( - communityUuid, + senderCommunityUuid, gradidoID, alias ?? firstName ?? '', code, amount, memo, ) + // encode/sign the jwt with the private key of the sender/home community const homeCom = await getHomeCommunity() if (!homeCom.privateKey) { throw new LogError('Home community private key is not set') } const redeemJwt = await encode(disbursementJwtPayloadType, homeCom.privateKey) + // TODO: encrypt the payload with the public key of the target community return redeemJwt } diff --git a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue index 0ef16f25a..edf7f08a4 100644 --- a/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue +++ b/frontend/src/components/LinkInformations/RedeemCommunitySelection.vue @@ -16,11 +16,11 @@ - +

{{ $t('gdd_per_link.switchCommunity') }}

{{ $t('gdd_per_link.to-switch') }} @@ -47,25 +47,69 @@ const props = defineProps({ linkData: { type: Object, required: true }, redeemCode: { type: String, required: true }, isContributionLink: { type: Boolean, default: false }, - targetCommunity: { + receiverCommunity: { type: Object, - required: true, - default: () => ({ uuid: '', name: CONFIG.COMMUNITY_NAME }), + required: false, }, }) -const emit = defineEmits(['update:targetCommunity']) +const senderCommunity = computed(() => extractHomeCommunityFromLinkData(props.linkData)) +const currentReceiverCommunity = computed( + () => + props.receiverCommunity || { + uuid: senderCommunity.value.uuid, + name: senderCommunity.value.name, + url: senderCommunity.value.url, + foreign: senderCommunity.value.foreign, + }, +) + +const emit = defineEmits(['update:receiverCommunity']) const isForeignCommunitySelected = computed(() => { - if (props.targetCommunity.name !== CONFIG.COMMUNITY_NAME) { - return true - } - return false + console.log( + 'RedeemCommunitySelection.isForeignCommunitySelected...receiverCommunity=', + currentReceiverCommunity.value, + ) + return currentReceiverCommunity.value.foreign }) -function setTargetCommunity(community) { - console.log('RedeemCommunitySelection.setTargetCommunity...community=', community) - emit('update:targetCommunity', community) +function setReceiverCommunity(community) { + console.log('RedeemCommunitySelection.setReceiverCommunity...community=', community) + emit('update:receiverCommunity', { + uuid: community.uuid, + name: community.name, + url: community.url, + foreign: community.foreign, + }) +} + +function extractHomeCommunityFromLinkData(linkData) { + console.log('RedeemCommunitySelection.extractHomeCommunityFromLinkData...linkData=', linkData) + if (linkData.communities.length === 0) { + return { + uuid: '', + name: CONFIG.COMMUNITY_NAME, + url: CONFIG.COMMUNITY_URL, + foreign: false, + } + } + const communities = linkData.communities + console.log( + 'RedeemCommunitySelection.extractHomeCommunityFromLinkData...communities=', + communities, + ) + const homeCommunity = communities.find((c) => c.foreign === false) + console.log( + 'RedeemCommunitySelection.extractHomeCommunityFromLinkData...homeCommunity=', + homeCommunity, + ) + return { + uuid: homeCommunity.uuid, + name: homeCommunity.name, + url: homeCommunity.url, + foreign: homeCommunity.foreign, + } } const { mutate: createRedeemJwt } = useMutation(createRedeemJwtMutation) @@ -76,8 +120,9 @@ async function onSwitch(event) { if (isForeignCommunitySelected.value) { console.log('RedeemCommunitySelection.onSwitch vor createRedeemJwt params:', { gradidoID: props.linkData.user.gradidoID, - communityUuid: props.targetCommunity.uuid, - communityName: props.targetCommunity.name, + senderCommunityUuid: senderCommunity.value.uuid, + senderCommunityName: senderCommunity.value.name, + receiverCommunityUuid: currentReceiverCommunity.value.uuid, code: props.redeemCode, amount: props.linkData.amount, memo: props.linkData.memo, @@ -87,8 +132,9 @@ async function onSwitch(event) { try { const { data } = await createRedeemJwt({ gradidoID: props.linkData.user.gradidoID, - communityUuid: props.targetCommunity.uuid, - communityName: props.targetCommunity.name, + senderCommunityUuid: senderCommunity.value.uuid, + senderCommunityName: senderCommunity.value.name, + receiverCommunityUuid: currentReceiverCommunity.value.uuid, code: props.redeemCode, amount: props.linkData.amount, memo: props.linkData.memo, @@ -99,7 +145,7 @@ async function onSwitch(event) { if (!data?.createRedeemJwt) { throw new Error('Failed to get redeem token') } - const targetUrl = props.targetCommunity.url.replace(/\/api\/?$/, '') + const targetUrl = currentReceiverCommunity.value.url.replace(/\/api\/?$/, '') window.location.href = targetUrl + '/redeem/' + data.createRedeemJwt } catch (error) { console.error('RedeemCommunitySelection.onSwitch error:', error) diff --git a/frontend/src/components/LinkInformations/RedeemSelectCommunity.vue b/frontend/src/components/LinkInformations/RedeemSelectCommunity.vue index d956dce1a..7910a4032 100644 --- a/frontend/src/components/LinkInformations/RedeemSelectCommunity.vue +++ b/frontend/src/components/LinkInformations/RedeemSelectCommunity.vue @@ -1,7 +1,7 @@ diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 10ed5944a..315444f84 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -202,8 +202,9 @@ export const logout = gql` export const createRedeemJwtMutation = gql` mutation ( $gradidoID: String! - $communityUuid: String! - $communityName: String! + $senderCommunityUuid: String! + $senderCommunityName: String! + $receiverCommunityUuid: String! $code: String! $amount: String! $memo: String! @@ -212,8 +213,9 @@ export const createRedeemJwtMutation = gql` ) { createRedeemJwt( gradidoID: $gradidoID - communityUuid: $communityUuid - communityName: $communityName + senderCommunityUuid: $senderCommunityUuid + senderCommunityName: $senderCommunityName + receiverCommunityUuid: $receiverCommunityUuid code: $code amount: $amount memo: $memo