Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

RFC: Use io-ts to validate user input. #65

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

BenPope
Copy link
Contributor

@BenPope BenPope commented Dec 16, 2019

RFC: This implements checks for RemoveRoomRoleForUserOptions only.

  • How much existing code will break; should the checks be for values only?
  • Is there a better way to allowJs without removed declaration: true
  • Are the dependencies ok?
  • is Update io-ts, fp-ts, typescript #67 OK?
  • Is the new semver ok?

What?

Define the requirements in terms of io-ts types and check them at runtime.
Add tests for Room Roles

Why?

When the typescript is converted to javascript, all type checks are lost.


  • CHANGELOG updated if relevant?

When the typescript is converted to javascript, all type checks are lost.

Instead, define the requirements in terms of io-ts types and check them at runtime.
Copy link
Contributor

@minaorangina minaorangina left a comment

Choose a reason for hiding this comment

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

This is fine in theory. It's hard to know if this doesn't break anything, in particular after the removal of Babel. It seems like it's unused, but I'm not wholly confident that the tests would pick this up 😅

package.json Outdated
@@ -41,6 +46,6 @@
"publish-please": "^5.1.1",
"tap-colorize": "^1.2.0",
"tape": "^4.9.1",
"typescript": "^2.6.1"
"typescript": "^2.8.1"
Copy link
Contributor

Choose a reason for hiding this comment

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

May as well bump to 2.8.3, which includes some bug fixes

src/chatkit.ts Outdated
import * as t from 'io-ts'
import "unknown-ts"

const NonEmptyString = t.refinement(t.string, s => s.length != 0, "NonEmptyString");
Copy link
Contributor

Choose a reason for hiding this comment

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

Though it wouldn't make a difference here, triple equals is always preferred (i.e. !==)

src/chatkit.ts Outdated
userId: NonEmptyString
},"UserIdOptions");
type UserIdOptions = t.TypeOf<typeof UserIdOptions>;
export { UserIdOptions };
Copy link
Contributor

Choose a reason for hiding this comment

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

The use of the same name for two different things is confusing at a glance (though I know you mentioned the docs gave an example like this)

@callum-oakley
Copy link
Contributor

callum-oakley commented Jan 2, 2020

I like it. Hadn't seen io-ts before. It is a whole bunch of extra machinery though... and I'd be happier if we were using it everywhere, but maybe using it in this one method is a good test bed for whether we want to put the work in to do it for the whole API?

When you say should the check be for values only... do you mean that some people might be feeding numbers to removeRoomRoleForUser, and it wouldn't have been an issue before, but now it will be? If so I don't feel strongly about it. The public interface has always been documented as taking strings, so it's not strictly a breaking change to start rejecting non-strings.

I think the real issue here is with the API being too "clever" and interpreting an empty string room ID as indicating a global role. Maybe we should change that in V7 instead and then all the SDKs would get this fix for free. I'd be surprised if this issue didn't also feature in all our other SDKs.

src/chatkit.ts Outdated
import * as t from 'io-ts'
import "unknown-ts"

const NonEmptyString = t.refinement(t.string, s => s.length !== 0, "NonEmptyString");
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to be more restrictive; it won't take an normal string.
error TS2322: Type 'string' is not assignable to type 'Branded<string, NonEmptyStringBrand>'. Type 'string' is not assignable to type 'Brand<NonEmptyStringBrand>'.

Copy link
Contributor

Choose a reason for hiding this comment

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

ah I see. never mind then

Update io-ts, fp-ts, typescript
@BenPope
Copy link
Contributor Author

BenPope commented Jan 2, 2020

I like it. Hadn't seen io-ts before. It is a whole bunch of extra machinery though... and I'd be happier if we were using it everywhere, but maybe using it in this one method is a good test bed for whether we want to put the work in to do it for the whole API?

The intention is to use it everywhere.

When you say should the check be for values only... do you mean that some people might be feeding numbers to removeRoomRoleForUser, and it wouldn't have been an issue before, but now it will be?

More likely it would be a parameter on another method, perhaps messageId.

If so I don't feel strongly about it. The public interface has always been documented as taking strings, so it's not strictly a breaking change to start rejecting non-strings.

Fair enough.

I think the real issue here is with the API being too "clever" and interpreting an empty string room ID as indicating a global role. Maybe we should change that in V7 instead and then all the SDKs would get this fix for free. I'd be surprised if this issue didn't also feature in all our other SDKs.

That makes sense to me.

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

Successfully merging this pull request may close these issues.

3 participants