[PM-36132] add tiktok login qualifiers#24
Conversation
🤖 Bitwarden Claude Code ReviewOverall Assessment: APPROVE Reviewed the addition of Code Review DetailsNo new findings beyond those already raised and addressed by the human reviewers:
|
| "username": ["input[name='username']"], | ||
| "password": ["input[type='password']"] |
There was a problem hiding this comment.
| "username": ["input[name='username']"], | |
| "password": ["input[type='password']"] | |
| "username": ["div#loginContainer input[name='username']"], | |
| "password": ["div#loginContainer input[type='password']"] |
There was a problem hiding this comment.
It seems strange to me that those fields are not relative to "container". It's noted as such in the docs. The examples, however, are misleading.
Addressed by 9570c0c
There was a problem hiding this comment.
A consumer should be able to determine what value belongs in the field from the key name and form category alone. Selector specificity should not rely on other selectors (e.g. container selector).
The primary reason for this is that the container is optional, and also can exist without having the related inputs directly inside it (I'm thinking particularly of controlled form scenarios). If we allow the inputs to use the form selectors as bounding contexts, we both prescribe that a consumer must consider both selectors, and that inputs must be within a container if one is described (which, to be fair, is exceedingly common, despite not being guaranteed).
I think it would make sense to revisit this after some time working with the Forms map if we find it to be more onerous than flexible, but I'd like to advocate that we stick with the convention for now and see.
There was a problem hiding this comment.
If we allow the inputs to use the form selectors as bounding contexts, we both prescribe that a consumer must consider both selectors, and that inputs must be within a container if one is described (which, to be fair, is exceedingly common, despite not being guaranteed).
I think a bounding context is implied by the name "container". I wouldn't think that you mean "form" when you say "container".
("see edit history, I accidentally overwrote this comment when trying to add a new one" -@jprusik)
There was a problem hiding this comment.
I think a bounding context is implied by the name "container". I wouldn't think that you mean "form" when you say "container".
I agree with that; the challenge was disambiguating between "form" as a represented concept, <form> as a tag, and the visual grouping of related fields. The three categories often overlap, but drift from each other often enough that we needed a name for "the thing the fields are anchored to"; it quite possibly needs refinement.
Part of me wonders if it's useful to describe that at all.
There was a problem hiding this comment.
("see edit history, I accidentally overwrote this comment when trying to add a new one" -@jprusik)
😂 I very nearly did this to one of your comments, too, when I was adding an "addressed by $revision"
| "button[data-e2e='login-button']", | ||
| "button[type='submit']" |
There was a problem hiding this comment.
Similar to the suggestion above, unless the buttons exist adjacent to the form container (which is sometimes the case), include the container selector to avoid matches against other buttons on the page (particularly the second one)
| "button[data-e2e='login-button']", | |
| "button[type='submit']" | |
| "div#loginContainer button[data-e2e='login-button']", | |
| "div#loginContainer button[type='submit']" |
For the sign up flow on tiktok, we can add an account-creation that maps this input to phone.
For the login flow, would setting as username be sufficient since we can safely assume the user determined their login method before saving credentials or is this a path we should think of 🤔 @jprusik |
|
📝 The phone number field has a way to distinguish it from a username and you can log in with a phone and username by clicking "use password" on the box. From a mapping perspective, I could make it a late-binding of the username field, and/or an early binding of a phone number field (as in, positioning the selector within an ordered list before/after its other matches). I tried making this more specific in d9a65ab. 🤔 The thing I wonder about, since we don't want this tied specifically to Bitwarden, is whether we'd want to distinguish sub-types of phone numbers. This field specifically needs to be one that can receive text messages. In that respect, it could even be used as part of, say, a mobile TOTP that expects you to enter the last-4 of your mobile number or some such thing. MtW isn't currently set up to handle this level of specificity. ❓ Another thing that I'm interested in is the |
| "phone": ["div#loginContainer form input[name='mobile']"], | ||
| "username": ["div#loginContainer form input[name='username']"], | ||
| "password": ["div#loginContainer form input[type='password']"] |
There was a problem hiding this comment.
username + password is a mutually exclusive login form to phone, so I think these need to be split to their own form entries for this host
(The sms send/entry in the phone login is arguably a form within a form, which we don't have a way to represent in the map, so I think we can set it to the side, for the moment)
| "email": ["div#loginContainer form input[name='email']"], | ||
| // field only distinguishable from `account-login` because the email field is present instead of `username` | ||
| "newPassword": [ | ||
| "div#loginContainer form:has(input[name='email']) input[type='password']" |
There was a problem hiding this comment.
form:has(input[name='email'])
love this; VERY nice fix for the problem
There was a problem hiding this comment.
non-blocking: shall we use this targeting technique in the other selectors to better distinguish between the otherwise identically-targeted-but-still-independent forms?
There was a problem hiding this comment.
I don't think that's necessary. The main reason why the newPassword field uses that selector is because there's an identical password input between account creation and login. Getting to that flow is buried in the TikTok UI, so I gave it that highly-specific selector.
I think the Forms Map would presently describe it as a
Yes, since it's a single, dual-purpose field |
Yeah, we'll have to think about this in our browser client implementation. I think the signal from this Map is fairly unambiguous though (via the form |
4e136ca to
f52a5d4
Compare
| "username": ["div#loginContainer form input[name='username']"], | ||
| "password": ["div#loginContainer form input[type='password']"] | ||
| "email": ["div#loginContainer form input[name='username']"], | ||
| "password": ["div#loginContainer form input[type='password']"], | ||
| "username": ["div#loginContainer form input[name='username']"] |


🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-36132
📔 Objective
Map TikTok's login fields.