Skip to content

Commit

Permalink
error validation for credentials actions
Browse files Browse the repository at this point in the history
  • Loading branch information
achowdhry-ripple committed Nov 15, 2024
1 parent 263fce7 commit 6d023f7
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 11 deletions.
9 changes: 8 additions & 1 deletion packages/xrpl/src/models/transactions/CredentialAccept.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { BaseTransaction } from '../../../dist/npm'

import { validateBaseTransaction } from './common'
import { validateBaseTransaction, validateCredentialType } from './common'

/**
* Credentials are represented in hex. Whilst they are allowed a maximum length of 64
* bytes, every byte requires 2 hex characters for representation
*/

/**
* accepts a credential issued to the Account (i.e. the Account is the Subject of the Credential object).
Expand Down Expand Up @@ -29,4 +34,6 @@ export interface CredentialAccept extends BaseTransaction {
*/
export function validateCredentialAccept(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)

validateCredentialType(tx.CredentialType)
}
8 changes: 7 additions & 1 deletion packages/xrpl/src/models/transactions/CredentialCreate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BaseTransaction } from '../../../dist/npm'

import { validateBaseTransaction } from './common'
import { validateBaseTransaction, validateCredentialType } from './common'

const MAX_URI_LENGTH = 256

/**
* Creates a Credential object. It must be sent by the issuer.
Expand Down Expand Up @@ -34,4 +36,8 @@ export interface CredentialCreate extends BaseTransaction {
*/
export function validateCredentialCreate(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)

validateURI(tx.URI)

validateCredentialType(tx.CredentialType)
}
13 changes: 11 additions & 2 deletions packages/xrpl/src/models/transactions/CredentialDelete.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BaseTransaction } from '../../../dist/npm'
import { ValidationError } from '../../errors'

import { validateBaseTransaction } from './common'
import { validateBaseTransaction, validateCredentialType } from './common'

/**
* Deletes a Credential object.
Expand Down Expand Up @@ -31,4 +32,12 @@ export interface CredentialDelete extends BaseTransaction {
*/
export function validateCredentialDelete(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
}

if (!tx.Account && !tx.Issuer) {
throw new ValidationError(
'CredentialDelete: Neither `issuer` nor `subject` was provided',
)
}

validateCredentialType(tx.CredentialType)
}.
26 changes: 26 additions & 0 deletions packages/xrpl/src/models/transactions/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HEX_REGEX } from '@xrplf/isomorphic/dist/utils'
import { isValidClassicAddress, isValidXAddress } from 'ripple-address-codec'
import { TRANSACTION_TYPES } from 'ripple-binary-codec'

Expand Down Expand Up @@ -366,3 +367,28 @@ export function parseAmountValue(amount: unknown): number {
}
return parseFloat(amount.value)
}

const MAX_CREDENTIAL_TYPE_LENGTH = 64 * 2
/**
* Check a CredentialType for formatting errors
*
* @param credentialType A credential type field to check for errors
* @throws Validation Error if the formatting is incorrect
*/
export function validateCredentialType(credentialType: string): void {
if (credentialType.length === 0) {
throw new ValidationError(
'CredentialAccept: CredentialType length must be > 0.',
)
} else if (credentialType.length > MAX_CREDENTIAL_TYPE_LENGTH) {
throw new ValidationError(
`CredentialAccept: CredentialType length sust be < ${MAX_CREDENTIAL_TYPE_LENGTH}.`,
)
}

if (!HEX_REGEX.test(credentialType)) {
throw new ValidationError(
`CredentialAccept: CredentialType myust be encoded in hex.`,
)
}
}
20 changes: 13 additions & 7 deletions packages/xrpl/src/models/transactions/depositPreauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ export interface DepositPreauth extends BaseTransaction {
export function validateDepositPreauth(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)

if (tx.Authorize !== undefined && tx.Unauthorize !== undefined) {
throw new ValidationError(
"DepositPreauth: can't provide both Authorize and Unauthorize fields",
)
}
// Boolean logic to ensure exactly one of 4 inputs was provided
const normalAuthorizeXOR = !tx.Authorize !== !tx.Unauthorize
const authorizeCredentialsXOR =
!tx.AuthorizeCredentials !== !tx.UnauthorizeCredentials

if (tx.Authorize === undefined && tx.Unauthorize === undefined) {
if (normalAuthorizeXOR === authorizeCredentialsXOR) {
throw new ValidationError(
'DepositPreauth: must provide either Authorize or Unauthorize field',
'DepositPreauth txn requires exactly one input amongst authorize, unauthorize, authorize_credentials and unauthorize_credentials.',
)
}

if (tx.Authorize !== undefined) {
// is this needed
if (typeof tx.Authorize !== 'string') {
throw new ValidationError('DepositPreauth: Authorize must be a string')
}
Expand All @@ -58,6 +58,12 @@ export function validateDepositPreauth(tx: Record<string, unknown>): void {
}
}

if (tx.AuthorizeCredentials) {
validateCredentialsList(tx.AuthorizeCredentials)
} else if (tx.UnauthorizeCredentials) {
validateCredentialsList(tx.UnauthorizeCredentials)
}

if (tx.Unauthorize !== undefined) {
if (typeof tx.Unauthorize !== 'string') {
throw new ValidationError('DepositPreauth: Unauthorize must be a string')
Expand Down

0 comments on commit 6d023f7

Please sign in to comment.