-
Notifications
You must be signed in to change notification settings - Fork 12
feat: identifier first login, reset password overhaul #759
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #759 +/- ##
=======================================
Coverage 44.72% 44.72%
=======================================
Files 39 39
Lines 3204 3204
=======================================
Hits 1433 1433
Misses 1688 1688
Partials 83 83 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
916da45
to
0e898b6
Compare
0e898b6
to
f39613f
Compare
f39613f
to
b627325
Compare
const renderFlow: LoginFlow | undefined = flow | ||
? isIdentifierFirst | ||
? { | ||
...flow, | ||
ui: { | ||
...flow.ui, | ||
nodes: flow.ui.nodes.filter((n: UiNode) => { | ||
if ( | ||
n.attributes.node_type === "input" && | ||
typeof (n.attributes as UiNodeInputAttributes).name === "string" | ||
) { | ||
const name = (n.attributes as UiNodeInputAttributes).name; | ||
return ( | ||
name === "identifier" || | ||
name === "csrf_token" || | ||
name === "method" | ||
); | ||
} | ||
return false; | ||
}), | ||
}, | ||
} | ||
: isAuthCode | ||
? filterFlow(replaceAuthLabel(flow)) | ||
: flow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: nested ternary operator inside ternary operator == hurts to read
we need to improve readability of the code, can you please break it down?
ui/pages/login.tsx
Outdated
const title = isIdentifierFirst | ||
? "Sign in" | ||
: isAuthCode | ||
? "Verify your identity" | ||
: `Sign in${getTitleSuffix()}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue(readability): same as below
ui/components/Password.tsx
Outdated
onChange={(e) => { | ||
if (!hasTouched) setHasTouched(true); | ||
setPassword(e.target.value); | ||
}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please move the inline function to a React.useCallback?
ui/components/Password.tsx
Outdated
const validateCheck = (check: PasswordCheckType, value: string): boolean => { | ||
switch (check) { | ||
case "lowercase": | ||
return /[a-z]/.test(password) ? "success" : "error"; | ||
return /[a-z]/.test(value); | ||
case "uppercase": | ||
return /[A-Z]/.test(password) ? "success" : "error"; | ||
return /[A-Z]/.test(value); | ||
case "number": | ||
return /[0-9]/.test(password) ? "success" : "error"; | ||
return /\d/.test(value); | ||
case "length": | ||
return password.length >= 8 ? "success" : "error"; | ||
return value.length >= 8; | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue(readability): please move this function out to refactor it to a static function, so the body of the component is not made heavy to read
ui/components/NodeInputPassword.tsx
Outdated
setPassword(e.target.value); | ||
void setValue(e.target.value); | ||
}} | ||
onKeyDown={(e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment on inline function
ui/pages/login.tsx
Outdated
return fetch( | ||
`/api/kratos/self-service/login/id-first?flow=${encodeURIComponent(flowId)}`, | ||
{ | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ | ||
...values, | ||
method, | ||
flow: String(flow?.id), | ||
}), | ||
}, | ||
) | ||
.then(async (res) => { | ||
if (!res.ok) { | ||
throw new Error(await res.text()); | ||
} | ||
return (await res.json()) as IdentifierFirstResponse; | ||
}) | ||
.then((data) => { | ||
if ("redirect_to" in data) { | ||
window.location.href = data.redirect_to; | ||
return; | ||
} | ||
if (flow?.return_to) { | ||
window.location.href = flow.return_to; | ||
return; | ||
} | ||
setFlow(data); | ||
}) | ||
.catch(redirectToErrorPage); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this should be in a function, ideally I think it should be part of the kratos
object (defined in kratos.ts
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't it be a method in the kratos sdk object? Also it should re-use the basePath
from Kratos sdk, this way we treat it as a single API and if we want to refactor it in the future (e.g. change the basePath) we would just have to change the sdk instantiation instead of having to search the code for hard coded strings.
665f045
to
6204892
Compare
Identifier first login
Screen.Recording.2025-09-25.at.8.05.16.PM.mov
Email validation
Reset Password
Screen.Recording.2025-09-25.at.8.09.21.PM.mov