Skip to content

Commit

Permalink
[PLA-1861] Updates and tweaks for dealing with single use codes. (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
v16Studios authored Jun 17, 2024
1 parent eae56a4 commit ca60c9f
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/GraphQL/Mutations/ClaimBeamMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ protected function rules(array $args = []): array
{
$beamCode = null;
if ($singleUse = BeamService::isSingleUse($args['code'])) {
$beamCode = explode(':', decrypt($args['code']), 3)[1] ?? null;
$beamCode = BeamService::getSingleUseCodeData($args['code'])?->beamCode;
}

return [
Expand Down
17 changes: 15 additions & 2 deletions src/GraphQL/Queries/GetPendingClaimsQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Closure;
use Enjin\Platform\Beam\Models\BeamClaim;
use Enjin\Platform\Beam\Rules\BeamExists;
use Enjin\Platform\Beam\Services\BeamService;
use Enjin\Platform\GraphQL\Types\Pagination\ConnectionInput;
use Enjin\Platform\Interfaces\PlatformPublicGraphQlOperation;
use Enjin\Platform\Rules\ValidSubstrateAccount;
Expand Down Expand Up @@ -61,6 +63,10 @@ public function resolve(
ResolveInfo $resolveInfo,
Closure $getSelectFields
) {
if ($beamData = BeamService::getSingleUseCodeData($args['code'])) {
$args['code'] = $beamData->beamCode;
}

return BeamClaim::loadSelectFields($resolveInfo, $this->name)
->hasCode(Arr::get($args, 'code'))
->where('wallet_public_key', SS58Address::getPublicKey(Arr::get($args, 'account')))
Expand All @@ -73,8 +79,15 @@ public function resolve(
protected function rules(array $args = []): array
{
return [
'code' => ['filled', 'max:1024', 'exists:beams,code,deleted_at,NULL'],
'account' => ['filled', new ValidSubstrateAccount()],
'code' => [
'filled',
'max:1024',
new BeamExists(),
],
'account' => [
'filled',
new ValidSubstrateAccount(),
],
];
}
}
4 changes: 2 additions & 2 deletions src/Models/Laravel/BeamClaim.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ public function scopeSingleUse(Builder $query): Builder
*/
public function scopeWithSingleUseCode(Builder $query, string $code): Builder
{
$parsed = explode(':', decrypt($code), 3);
$parsed = BeamService::getSingleUseCodeData($code);

return $query->where(['code' => $parsed[0], 'nonce' => $parsed[2]]);
return $query->where(['code' => $parsed->claimCode, 'nonce' => $parsed->nonce]);
}

/**
Expand Down
12 changes: 10 additions & 2 deletions src/Models/Laravel/Traits/HasCodeScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace Enjin\Platform\Beam\Models\Laravel\Traits;

use Enjin\Platform\Beam\Services\BeamService;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Support\Arr;

trait HasCodeScope
{
Expand All @@ -12,6 +12,14 @@ trait HasCodeScope
*/
public function scopeHasCode(Builder $query, string|array|null $code): Builder
{
return $query->whereHas('beam', fn ($query) => $query->whereIn('code', Arr::wrap($code)));
$codes = collect($code)->map(function ($code) {
if (BeamService::isSingleUse($code)) {
return BeamService::getSingleUseCodeData($code)->beamCode;
}

return $code;
})->toArray();

return $query->whereHas('beam', fn ($query) => $query->whereIn('code', $codes));
}
}
5 changes: 3 additions & 2 deletions src/Models/Laravel/Traits/HasSingleUseCodeScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Enjin\Platform\Beam\Models\Laravel\Traits;

use Enjin\Platform\Beam\Services\BeamService;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Support\Arr;

Expand All @@ -15,10 +16,10 @@ public function scopeHasSingleUseCode(Builder $query, string|array|null $code):
try {
if (is_array($code)) {
$singleUseCode = array_map(function ($item) {
return explode(':', decrypt($item))[0];
return BeamService::getSingleUseCodeData($item)?->claimCode;
}, $code);
} else {
$singleUseCode = explode(':', decrypt($code))[0];
$singleUseCode = BeamService::getSingleUseCodeData($code)?->claimCode;
}

return $query->whereIn('code', Arr::wrap($singleUseCode));
Expand Down
5 changes: 5 additions & 0 deletions src/Rules/BeamExists.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use Enjin\Platform\Beam\Models\Beam;
use Enjin\Platform\Beam\Services\BeamService;
use Illuminate\Contracts\Validation\ValidationRule;

class BeamExists implements ValidationRule
Expand All @@ -19,6 +20,10 @@ public function __construct(protected string $column = 'code')
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if ($beamData = BeamService::getSingleUseCodeData($value)) {
$value = $beamData->beamCode;
}

if (!Beam::where($this->column, $value)->exists()) {
$fail('validation.exists')->translate();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Rules/CanClaim.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
}

if ($this->singleUse) {
$value = explode(':', decrypt($value), 3)[1];
$value = BeamService::getSingleUseCodeData($value)?->beamCode;
} elseif (BeamService::hasSingleUse($value)) {
$fail('enjin-platform-beam::validation.can_claim')->translate();

Expand Down
2 changes: 1 addition & 1 deletion src/Rules/VerifySignedMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
}

if (BeamService::isSingleUse($this->data['code'])) {
$this->data['code'] = explode(':', decrypt($this->data['code']))[1];
$this->data['code'] = BeamService::getSingleUseCodeData($this->data['code'])?->beamCode;
}

if (!$scan = BeamScan::hasCode($this->data['code'])->firstWhere(['wallet_public_key' => $publicKey])) {
Expand Down
16 changes: 13 additions & 3 deletions src/Services/BeamService.php
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,22 @@ public static function isSingleUse(?string $code): bool
return false;
}

return static::hasSingleUse(static::getSingleUseCodeData($code)?->beamCode);
}

public static function getSingleUseCodeData(string $code): ?object
{
try {
return static::hasSingleUse(explode(':', decrypt($code), 3)[1] ?? null);
[$claimCode, $beamCode, $nonce] = explode(':', decrypt($code), 3);

return (object) [
'claimCode' => $claimCode,
'beamCode' => $beamCode,
'nonce' => $nonce,
];
} catch (Throwable) {
return null;
}

return false;
}

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/Feature/GraphQL/Queries/GetPendingClaimsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ public function test_it_can_get_pending_claims(): void
$this->assertEmpty($response['edges']);
}

/**
* Test get claims from single use code.
*/
public function test_it_can_get_pending_claims_using_single_use_code(): void
{
$response = $this->graphql($this->method, [
'code' => $this->beam->claims[0]->single_use_code,
'account' => $this->claims->first()->wallet_public_key,
]);
$this->assertNotEmpty($response['totalCount']);

$response = $this->graphql($this->method, [
'code' => $this->beam->claims[0]->single_use_code,
'account' => resolve(SubstrateProvider::class)->public_key(),
]);
$this->assertEmpty($response['edges']);
}

/**
* Test get claims with id and code.
*/
Expand Down

0 comments on commit ca60c9f

Please sign in to comment.