From 21cbfa654d2a3effa11b8b83404158256142c1d5 Mon Sep 17 00:00:00 2001 From: Iaroslav Gryshaiev Date: Thu, 2 Jan 2025 21:06:17 +0100 Subject: [PATCH] fix(user): revoke stale users expired grants --- .../services/balances/balances.service.ts | 2 +- .../managed-user-wallet.service.ts | 2 +- apps/api/test/functional/start-trial.spec.ts | 2 +- .../src/queries/useBalancesQuery.ts | 2 +- .../queries/useExactDeploymentGrantsQuery.ts | 2 +- .../http-sdk/src/authz/authz-http.service.ts | 30 +++++++++++++++---- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/api/src/billing/services/balances/balances.service.ts b/apps/api/src/billing/services/balances/balances.service.ts index 7199cf52c..c9841db0b 100644 --- a/apps/api/src/billing/services/balances/balances.service.ts +++ b/apps/api/src/billing/services/balances/balances.service.ts @@ -62,7 +62,7 @@ export class BalancesService { async retrieveDeploymentLimit(userWallet: Pick): Promise { const masterWalletAddress = await this.masterWallet.getFirstAddress(); - const depositDeploymentGrant = await this.authzHttpService.getDepositDeploymentGrantsForGranterAndGrantee(masterWalletAddress, userWallet.address); + const depositDeploymentGrant = await this.authzHttpService.getValidDepositDeploymentGrantsForGranterAndGrantee(masterWalletAddress, userWallet.address); if (!depositDeploymentGrant || depositDeploymentGrant.authorization.spend_limit.denom !== this.config.DEPLOYMENT_GRANT_DENOM) { return 0; diff --git a/apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.ts b/apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.ts index e1f8779df..415ff3cec 100644 --- a/apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.ts +++ b/apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.ts @@ -124,7 +124,7 @@ export class ManagedUserWalletService { messages.push(this.rpcMessageService.getRevokeAllowanceMsg(params)); } - if (await this.authzHttpService.hasValidDepositDeploymentGrant(params.granter, params.grantee)) { + if (await this.authzHttpService.hasDepositDeploymentGrant(params.granter, params.grantee)) { revokeSummary.deploymentGrant = true; messages.push(this.rpcMessageService.getRevokeDepositDeploymentGrantMsg(params)); } diff --git a/apps/api/test/functional/start-trial.spec.ts b/apps/api/test/functional/start-trial.spec.ts index 71c1c1763..30900b3a6 100644 --- a/apps/api/test/functional/start-trial.spec.ts +++ b/apps/api/test/functional/start-trial.spec.ts @@ -44,7 +44,7 @@ describe("start trial", () => { const userWallet = await userWalletsQuery.findFirst({ where: eq(userWalletsTable.userId, userId) }); const masterWalletAddress = await resolveWallet("MANAGED").getFirstAddress(); const allowances = await Promise.all([ - authzHttpService.getDepositDeploymentGrantsForGranterAndGrantee(masterWalletAddress, userWallet.address), + authzHttpService.getValidDepositDeploymentGrantsForGranterAndGrantee(masterWalletAddress, userWallet.address), authzHttpService.getValidFeeAllowancesForGrantee(userWallet.address) ]); diff --git a/apps/deploy-web/src/queries/useBalancesQuery.ts b/apps/deploy-web/src/queries/useBalancesQuery.ts index 6816c9767..7d5538b38 100644 --- a/apps/deploy-web/src/queries/useBalancesQuery.ts +++ b/apps/deploy-web/src/queries/useBalancesQuery.ts @@ -20,7 +20,7 @@ async function getBalances(apiEndpoint: string, address?: string): Promise(ApiUrlService.balance(apiEndpoint, address)), - authzHttpService.getDepositDeploymentGrantsForGranterAndGrantee(browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS, address), + authzHttpService.getValidDepositDeploymentGrantsForGranterAndGrantee(browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS, address), loadWithPagination(ApiUrlService.deploymentList(apiEndpoint, address, true), "deployments", 1000) ]); diff --git a/apps/deploy-web/src/queries/useExactDeploymentGrantsQuery.ts b/apps/deploy-web/src/queries/useExactDeploymentGrantsQuery.ts index 5f2880f07..92421a55f 100644 --- a/apps/deploy-web/src/queries/useExactDeploymentGrantsQuery.ts +++ b/apps/deploy-web/src/queries/useExactDeploymentGrantsQuery.ts @@ -7,7 +7,7 @@ export function useExactDeploymentGrantsQuery(granter: string, grantee: string, const allowanceHttpService = useAuthZService(); return useQuery( QueryKeys.getDeploymentGrantsKey(granter, grantee), - () => allowanceHttpService.getDepositDeploymentGrantsForGranterAndGrantee(granter, grantee), + () => allowanceHttpService.getValidDepositDeploymentGrantsForGranterAndGrantee(granter, grantee), { enabled } diff --git a/packages/http-sdk/src/authz/authz-http.service.ts b/packages/http-sdk/src/authz/authz-http.service.ts index 251fff512..811f5d4c6 100644 --- a/packages/http-sdk/src/authz/authz-http.service.ts +++ b/packages/http-sdk/src/authz/authz-http.service.ts @@ -80,6 +80,18 @@ export class AuthzHttpService extends HttpService { } async getDepositDeploymentGrantsForGranterAndGrantee(granter: string, grantee: string): Promise { + const response = this.extractData( + await this.get>("cosmos/authz/v1beta1/grants", { + params: { + grantee: grantee, + granter: granter + } + }) + ); + return response.grants.find(grant => this.isDepositDeploymentGrant(grant)); + } + + async getValidDepositDeploymentGrantsForGranterAndGrantee(granter: string, grantee: string): Promise { const response = this.extractData( await this.get>("cosmos/authz/v1beta1/grants", { params: { @@ -101,10 +113,14 @@ export class AuthzHttpService extends HttpService { return feeAllowances.some(allowance => allowance.granter === granter); } - async hasValidDepositDeploymentGrant(granter: string, grantee: string) { + async hasDepositDeploymentGrant(granter: string, grantee: string) { return !!(await this.getDepositDeploymentGrantsForGranterAndGrantee(granter, grantee)) } + async hasValidDepositDeploymentGrant(granter: string, grantee: string) { + return !!(await this.getValidDepositDeploymentGrantsForGranterAndGrantee(granter, grantee)) + } + async paginateDepositDeploymentGrants( options: ({ granter: string } | { grantee: string }) & { limit: number }, cb: (page: DepositDeploymentGrantResponse["grants"]) => Promise @@ -140,11 +156,15 @@ export class AuthzHttpService extends HttpService { return result; } - private isValidFeeAllowance({ allowance }: FeeAllowance) { - return allowance["@type"] === this.FEE_ALLOWANCE_TYPE && (!allowance.expiration || isFuture(new Date(allowance.expiration))); + private isValidFeeAllowance(allowance: FeeAllowance) { + return (!allowance.allowance.expiration || isFuture(new Date(allowance.allowance.expiration))); + } + + private isValidDepositDeploymentGrant(grant: ExactDepositDeploymentGrant) { + return this.isDepositDeploymentGrant(grant) && (!grant.expiration || isFuture(new Date(grant.expiration))); } - private isValidDepositDeploymentGrant({ authorization, expiration }: ExactDepositDeploymentGrant) { - return authorization["@type"] === this.DEPOSIT_DEPLOYMENT_GRANT_TYPE && (!expiration || isFuture(new Date(expiration))); + private isDepositDeploymentGrant({ authorization }: ExactDepositDeploymentGrant) { + return authorization["@type"] === this.DEPOSIT_DEPLOYMENT_GRANT_TYPE; } }