-
Notifications
You must be signed in to change notification settings - Fork 283
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
Login with Passkeys!! #1599
base: trunk
Are you sure you want to change the base?
Login with Passkeys!! #1599
Conversation
Generated by 🚫 Danger |
You can test the changes in simplenote-ios from this Pull Request by:
|
…ge by ensuring it is url safe.
static let passkeyCredentialCreationURL = currentPasskeyBaseURL.appendingPathComponent("/api2/login") | ||
static let passkeyRegistrationURL = currentPasskeyBaseURL.appendingPathComponent("/auth/add-credential") | ||
static let passkeyAuthChallengeURL = currentPasskeyBaseURL.appendingPathComponent("/auth/prepare-auth-challenge") | ||
static let verifyPasskeyAuthChallengeURL = currentPasskeyBaseURL.appendingPathComponent("/auth/verify-login-credential") |
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 add a /
onto the end of all of these endpoints? It will save app engine from doing a redirect.
|
||
body += Data("--\(boundary)--\r\n".utf8) | ||
|
||
return body |
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.
Rather than converting every line into Data
, adding them all up and returning, we can build the string and convert just once, in the last statement
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.
Sending you a few notes, looking great Charlie!!
//TODO: Handle errors | ||
//TODO: Handle email not valid | ||
let passkeyAuthenticator = SPAppDelegate.shared().passkeyAuthenticator | ||
try? await passkeyAuthenticator.attemptPasskeyAuth(for: email, in: self) |
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.
SPAuthViewController
has an instance of SPAuthHandler
, which, in turn, has a reference to SPAuthenticator
.
No need to use a singleton for this one! 😄
@@ -627,6 +643,7 @@ struct AuthenticationMode { | |||
let secondaryActionText: String? | |||
let secondaryActionAttributedText: NSAttributedString? | |||
let isPasswordHidden: Bool | |||
let isLogin: Bool |
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.
This property appears not to be in use anywhere, perhaps it's a leftover?
secondaryActionText: AuthenticationStrings.loginSecondaryAction, | ||
secondaryActionAttributedText: nil, | ||
isPasswordHidden: true, | ||
isLogin: true) |
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.
😎
userInfo: [NSLocalizedDescriptionKey: "Can't decode base64 string"]) | ||
} | ||
return data | ||
} |
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.
Caaaan we add a comment mentioning why this was required (rather than the standard initializer?)
Thank youuu!!
} | ||
|
||
private func performPasskeyAuthentication(with response: PasskeyAuthResponse) { | ||
let json = try! JSONEncoder().encode(response) |
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.
It should never crash, but perhaps we should avoid the force unwrap on this one
case let credential as ASAuthorizationPlatformPublicKeyCredentialAssertion: | ||
let response = PasskeyAuthResponse(from: credential) | ||
|
||
performPasskeyAuthentication(with: response) |
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.
Nipticky: Indentation is a bit off in these few lines
private let response: PasskeyRegistrationResponse.Response | ||
|
||
init?(from credentialRegistration: ASAuthorizationPlatformPublicKeyCredentialRegistration) { | ||
guard let email = SPAppDelegate.shared().simperium.user?.email, |
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.
We should get the email via parameter (rather than coupling the initializer with the AppDelegate)
Fix
To improve the security of Simplenote accounts we are trying to move away from email/password authentication as it is insecure at best. One of the things we are implementing is Passkeys. This will allow users to create and store passkeys on their apple device and when they go to log into their account rather than using an email and password they only need to put in their email and then use the local biometrics to receive a passkey and then authenticate into Simplenote.
This has a bunch of security benefits and should also help users keep from losing their passwords.
Sign up for passkeys:
RPReplay_Final1718384460.mp4
Login with passkeys:
RPReplay_Final1718384268.mp4
Test
Review
(Required) Add instructions for reviewers. For example:
Release
(Required) Add a concise statement to
RELEASE-NOTES.txt
if the changes should be included in release notes. Include details about updating the notes in this section. For example: