Skip to content

Commit

Permalink
fix: account update (#3720)
Browse files Browse the repository at this point in the history
  • Loading branch information
dolcalmi authored Dec 17, 2023
1 parent f8abb59 commit b52b55d
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 48 deletions.
5 changes: 4 additions & 1 deletion core/api/src/app/accounts/delete-business-map-info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { checkedToUsername } from "@/domain/accounts"
import { AccountValidator, checkedToUsername } from "@/domain/accounts"

import { AccountsRepository } from "@/services/mongoose/accounts"

export const deleteBusinessMapInfo = async ({
Expand All @@ -13,6 +14,8 @@ export const deleteBusinessMapInfo = async ({

const account = await accountsRepo.findByUsername(usernameChecked)
if (account instanceof Error) return account
const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator

const newAccount = { ...account, title: null, coordinates: null }

Expand Down
8 changes: 6 additions & 2 deletions core/api/src/app/accounts/mark-account-for-deletion.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { getBalanceForWallet, listWalletsByAccountId } from "@/app/wallets"
import { AccountStatus } from "@/domain/accounts"

import { AccountStatus, AccountValidator } from "@/domain/accounts"
import { AccountHasPositiveBalanceError } from "@/domain/authentication/errors"

import { IdentityRepository } from "@/services/kratos"
import { AccountsRepository, UsersRepository } from "@/services/mongoose"
import { addEventToCurrentSpan } from "@/services/tracing"
import { AccountsRepository, UsersRepository } from "@/services/mongoose"

export const markAccountForDeletion = async ({
accountId,
Expand All @@ -17,6 +19,8 @@ export const markAccountForDeletion = async ({
const accountsRepo = AccountsRepository()
const account = await accountsRepo.findById(accountId)
if (account instanceof Error) return account
const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator

const wallets = await listWalletsByAccountId(account.id)
if (wallets instanceof Error) return wallets
Expand Down
5 changes: 4 additions & 1 deletion core/api/src/app/accounts/update-account-level.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { checkedToAccountId } from "@/domain/accounts"
import { AccountValidator, checkedToAccountId } from "@/domain/accounts"

import { AccountsRepository } from "@/services/mongoose"

export const updateAccountLevel = async ({
Expand All @@ -15,6 +16,8 @@ export const updateAccountLevel = async ({

const account = await accountsRepo.findById(accountId)
if (account instanceof Error) return account
const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator

account.level = level
return accountsRepo.update(account)
Expand Down
9 changes: 8 additions & 1 deletion core/api/src/app/accounts/update-business-map-info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { checkedCoordinates, checkedMapTitle, checkedToUsername } from "@/domain/accounts"
import {
AccountValidator,
checkedCoordinates,
checkedMapTitle,
checkedToUsername,
} from "@/domain/accounts"
import { AccountsRepository } from "@/services/mongoose/accounts"

export const updateBusinessMapInfo = async ({
Expand All @@ -17,6 +22,8 @@ export const updateBusinessMapInfo = async ({

const account = await accountsRepo.findByUsername(usernameChecked)
if (account instanceof Error) return account
const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator

const coordinates = checkedCoordinates({ latitude, longitude })
if (coordinates instanceof Error) return coordinates
Expand Down
11 changes: 7 additions & 4 deletions core/api/src/app/admin/update-user-phone.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { markAccountForDeletion } from "@/app/accounts"
import { checkedToAccountId } from "@/domain/accounts"
import { AuthWithPhonePasswordlessService } from "@/services/kratos"
import { AccountsRepository } from "@/services/mongoose/accounts"

import { AccountValidator, checkedToAccountId } from "@/domain/accounts"

import { UsersRepository } from "@/services/mongoose/users"
import { addAttributesToCurrentSpan } from "@/services/tracing"
import { AccountsRepository } from "@/services/mongoose/accounts"
import { AuthWithPhonePasswordlessService } from "@/services/kratos"

export const updateUserPhone = async ({
accountId: accountIdRaw,
Expand All @@ -20,10 +22,11 @@ export const updateUserPhone = async ({
const accountsRepo = AccountsRepository()
const account = await accountsRepo.findById(accountId)
if (account instanceof Error) return account
const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator
const kratosUserId = account.kratosUserId

const usersRepo = UsersRepository()

const newUser = await usersRepo.findByPhone(phone)
if (!(newUser instanceof Error)) {
// if newUser exists, then we need to delete it (only if balance is 0
Expand Down
12 changes: 11 additions & 1 deletion core/api/src/servers/graphql-public-api-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
} from "@/services/tracing"

import { parseIps } from "@/domain/accounts-ips"
import { AccountStatus } from "@/domain/accounts"

const isAuthenticated = rule({ cache: "contextual" })((
_parent,
Expand All @@ -37,6 +38,15 @@ const isAuthenticated = rule({ cache: "contextual" })((
return "domainAccount" in ctx && !!ctx.domainAccount
})

const hasMutationPermissions = rule({ cache: "contextual" })((
_parent,
_args,
ctx: GraphQLPublicContext | GraphQLPublicContextAuth,
) => {
const isAuthenticated = "domainAccount" in ctx && !!ctx.domainAccount
return isAuthenticated && ctx.domainAccount.status === AccountStatus.Active
})

const setGqlContext = async (
req: Request,
_res: Response,
Expand Down Expand Up @@ -89,7 +99,7 @@ export async function startApolloServerForCoreSchema() {
...mutationFields.authed.atAccountLevel,
...mutationFields.authed.atWalletLevel,
})) {
authedMutationFields[key] = isAuthenticated
authedMutationFields[key] = hasMutationPermissions
}

const permissions = shield(
Expand Down
59 changes: 21 additions & 38 deletions core/api/test/bats/admin.bats
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,6 @@ TESTER_TOKEN_NAME="tester"
TESTER_PHONE="+19876543210"
username="user1"

exec_admin_graphql() {
local token=$1
local query_name=$2
local variables=${3:-"{}"}
echo "GQL query - token: ${token} - query: ${query_name} - vars: ${variables}"
echo "{\"query\": \"$(gql_admin_query $query_name)\", \"variables\": $variables}"

if [[ "${BATS_TEST_DIRNAME}" != "" ]]; then
run_cmd="run"
else
run_cmd=""
fi

gql_route="admin/graphql"

${run_cmd} curl -s \
-X POST \
-H "Oauth2-Token: $token" \
-H "Content-Type: application/json" \
-d "{\"query\": \"$(gql_admin_query $query_name)\", \"variables\": $variables}" \
"${GALOY_ENDPOINT}/${gql_route}"

echo "GQL output: '$output'"
}

gql_admin_query() {
cat "$(gql_admin_file $1)" | tr '\n' ' ' | sed 's/"/\\"/g'
}

gql_admin_file() {
echo "${BATS_TEST_DIRNAME:-${CORE_ROOT}/test/bats}/admin-gql/$1.gql"
}


@test "admin: perform admin queries/mutations" {
client=$(curl -L -s -X POST $HYDRA_ADMIN_API/admin/clients \
-H 'Content-Type: application/json' \
Expand All @@ -63,7 +29,7 @@ gql_admin_file() {
-H 'Content-Type: application/x-www-form-urlencoded' \
-u "$client_id:$client_secret" \
-d "grant_type=client_credentials" | jq -r '.access_token'
)
)

echo "admin_token: $admin_token"

Expand Down Expand Up @@ -122,7 +88,7 @@ gql_admin_file() {
exec_admin_graphql "$admin_token" 'account-details-by-username' "$variables"
refetched_id="$(graphql_output '.data.accountDetailsByUsername.id')"
[[ "$refetched_id" == "$id" ]] || exit 1

variables=$(
jq -n \
--arg level "TWO" \
Expand Down Expand Up @@ -150,6 +116,23 @@ gql_admin_file() {
account_status="$(graphql_output '.data.accountUpdateStatus.accountDetails.status')"
[[ "$account_status" == "LOCKED" ]] || exit 1

# User cannot delete the account if it is locked
exec_graphql "$TESTER_TOKEN_NAME" 'account-delete'
delete_error_message="$(graphql_output '.errors[0].message')"
[[ "$delete_error_message" == "Not authorized" ]] || exit 1

# Admin cannot update the phone if it is locked
new_phone="$(random_phone)"
variables=$(
jq -n \
--arg phone "$new_phone" \
--arg accountId "$id" \
'{input: {phone: $phone, accountId:$accountId}}'
)
exec_admin_graphql $admin_token 'user-update-phone' "$variables"
update_error_message="$(graphql_output '.data.userUpdatePhone.errors[0].message')"
[[ "$update_error_message" == "Account is inactive." ]] || exit 1

variables=$(
jq -n \
--arg accountId "$id" \
Expand All @@ -162,7 +145,7 @@ gql_admin_file() {

userId="$(graphql_output '.data.accountDetailsByAccountId.owner.id')"
echo "userId: $userId"

variables=$(
jq -n \
--arg userId "$userId" \
Expand All @@ -175,6 +158,6 @@ gql_admin_file() {


# TODO: add check by email

# TODO: business update map info
}
33 changes: 33 additions & 0 deletions core/api/test/bats/helpers/_common.bash
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,36 @@ is_contact() {
)
[[ "$fetched_username" == "$contact_username" ]] || return 1
}

exec_admin_graphql() {
local token=$1
local query_name=$2
local variables=${3:-"{}"}
echo "GQL query - token: ${token} - query: ${query_name} - vars: ${variables}"
echo "{\"query\": \"$(gql_admin_query $query_name)\", \"variables\": $variables}"

if [[ "${BATS_TEST_DIRNAME}" != "" ]]; then
run_cmd="run"
else
run_cmd=""
fi

gql_route="admin/graphql"

${run_cmd} curl -s \
-X POST \
-H "Oauth2-Token: $token" \
-H "Content-Type: application/json" \
-d "{\"query\": \"$(gql_admin_query $query_name)\", \"variables\": $variables}" \
"${GALOY_ENDPOINT}/${gql_route}"

echo "GQL output: '$output'"
}

gql_admin_query() {
cat "$(gql_admin_file $1)" | tr '\n' ' ' | sed 's/"/\\"/g'
}

gql_admin_file() {
echo "${BATS_TEST_DIRNAME:-${CORE_ROOT}/test/bats}/admin-gql/$1.gql"
}

0 comments on commit b52b55d

Please sign in to comment.