Skip to content

Conversation

hkarani
Copy link
Contributor

@hkarani hkarani commented Jul 16, 2025

Description

A clear and concise description of what you changed and why.

The client validation is changed to allow 0 by:

  • Changing the minimum allowed input to zero({min=0} in AdvPostForm component
  • Modifying the form validation in lib/validate.js to allow a minimum of 0

To only allow 0 to only pass the client:

  • The forwards are validated to be > 0 when normalizeForwards is called before mutuation in use-item-submit.js. normalizeForwards filters to remove forwards with 0 as pct.

Screenshots

Allow-0-pct-client-forwards

Additional Context

Was anything unclear during your work on this PR? Anything we should definitely take a closer look at?
No

Checklist

Are your changes backward compatible? Please answer below:

For example, a change is not backward compatible if you removed a GraphQL field or dropped a database column.

Only form validation and is changed when forwards are normalized.

On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:
8

For frontend changes: Tested on mobile, light and dark mode? Please answer below:
Yes

Did you introduce any new environment variables? If so, call them out explicitly here:
No

@hkarani hkarani force-pushed the allow-o-pct-client-forwards branch from 7f7e13e to 0bc3d89 Compare July 16, 2025 13:48
@hkarani hkarani requested review from huumn and SatsAllDay July 16, 2025 13:50
@@ -145,7 +145,7 @@ export function advPostSchemaMembers ({ me, existingBoost = 0, ...args }) {
},
message: 'cannot forward to yourself'
}),
pct: intValidator.required('must specify a percentage').min(1, 'percentage must be at least 1').max(100, 'percentage must not exceed 100')
pct: intValidator.required('must specify a percentage').min(0, 'percentage must be at least 0').max(100, 'percentage must not exceed 100')
Copy link
Member

@ekzyis ekzyis Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, this will allow to insert 0 pct forwards via the API because the server doesn't run normalizeForwards. Tested using the GraphQL playground at /api/graphql:

mutation upsertDiscussionWithForwards(
  $title: String!,
  $text: String!,
  $sub: String!,
  $forward: [ItemForwardInput]
) {
  upsertDiscussion(
    title: $title,
    text: $text,
    sub: $sub,
    forward: $forward
  ) {
    result {
      id
    }
  }
}

variables:

{
  "title": "foobar",
  "text": "asdf",
  "sub": "art",
  "forward": [{"nym":"anon","pct":0}]
}

I wish we could just do this:

diff --git a/lib/validate.js b/lib/validate.js
index 576687e6..68b5b204 100644
--- a/lib/validate.js
+++ b/lib/validate.js
@@ -129,6 +129,7 @@ export function advPostSchemaMembers ({ me, existingBoost = 0, ...args }) {
       }),
     forward: array()
       .max(MAX_FORWARDS, `you can only configure ${MAX_FORWARDS} forward recipients`)
+      .transform(forwards => forwards.filter(fwd => Number(fwd.pct) > 0))
       .of(object().shape({
         nym: string().required('must specify a stacker')
           .test({

but we can't since the transform only applies to the array during validation, the submitted array will be unmodified.

Maybe the proper fix would be to make validation return the transformed values in general; or only do so on the client, but the server always validates what it receives without any transforms. But this is a more general thing we would have to change in our code base.

Not sure how to fix this problem of allowing the client to submit something that the server shouldn't accept without too many changes and not making it confusing how it works :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback @ekzyis , I'll work to resolve this.

Curiously, do you use real sats in dev? I'd like to test this more before submitting the next change.

Copy link
Member

@ekzyis ekzyis Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curiously, do you use real sats in dev? I'd like to test this more before submitting the next change.

No, we don't, we have a regtest lightning network with multiple nodes.

When you set COMPOSE_PROFILES=minimal,payments in .env.local before you run sndev start, it will start them. See this section in the README.

But you can also use CCs via sndev set_balance <user> <balance>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification

Copy link
Contributor Author

@hkarani hkarani Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, this will allow to insert 0 pct forwards via the API because the server doesn't run normalizeForwards. Tested using the GraphQL playground at /api/graphql

I've tested this:
When normalizeForwards doesn't filter 0 pct forwards

Screen.Recording.2025-07-29.at.21.18.53.mov

Here we actually filter 0 before calling the mutation

https://github.com/stackernews/stacker.news/pull/2281/files#r2240699282

In use-item-submit

export default function useItemSubmit (mutation,
, upsertItem gets the the forwards after they are 0 pct items are filtered
forward: normalizeForwards(values.forward),

I still consider this the cleanest solution with no many code changes.

You can try it, test it yourself from the client and check the db for the items Forwards pcts, if this doesn't work for all intents and puporses this PR should be closed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O-pct.forwards.filtered.mov

Copy link
Member

@ekzyis ekzyis Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were looking at code that only runs in the client. What I meant here was that in theory, one does not have to use the client to make requests to our API. I gave you the GraphQL playground as an example.

As-is, the server does not filter out zero pct forwards but assumes the client already did it.

It is important in general that the server does not trust the client with inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caught that

@hkarani hkarani force-pushed the allow-o-pct-client-forwards branch from 0bc3d89 to 32ff229 Compare July 29, 2025 19:04
@hkarani hkarani closed this Aug 26, 2025
@huumn
Copy link
Member

huumn commented Aug 26, 2025

did you close this intentionally?

@hkarani
Copy link
Contributor Author

hkarani commented Aug 27, 2025

@ekzyis mentioned an issue with this. That's why I closed this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants