Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ struct SignInView: View {

func signIn() {
Task {
let result = await snapAuth.startAuth(.handle(userName))
let result = await snapAuth.startAuth(.username(userName))
switch result {
case .success(let auth):
// Send auth.token to your backend to sign in the user
Expand Down
2 changes: 2 additions & 0 deletions Sources/SnapAuth/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct SACreateRegisterOptionsResponse: Decodable {
struct SAProcessRegisterRequest: Encodable {
let credential: RegCredential

// See WebAuthn RegistrationResponseJSON format
struct RegCredential: Encodable {
let type: String = "public-key"
let rawId: Base64URL
Expand Down Expand Up @@ -113,6 +114,7 @@ struct SAProcessAuthRequest: Encodable {
// user ~ id/handle (skip for now since this is passkey only flow...ish)
let credential: SACredential
let user: AuthenticatingUser?
// See WebAuthn AuthenticationResponseJSON format
struct SACredential: Codable {
let type: String = "public-key"
let rawId: Base64URL
Expand Down
8 changes: 4 additions & 4 deletions Sources/SnapAuth/SnapAuth+BuildRequests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import AuthenticationServices
extension SnapAuth {
internal func buildRegisterRequests(
from options: SACreateRegisterOptionsResponse,
name: String,
username: String,
displayName: String?,
authenticators: Set<SnapAuth.Authenticator>
) -> [ASAuthorizationRequest] {
Expand All @@ -16,7 +16,7 @@ extension SnapAuth {
relyingPartyIdentifier: options.publicKey.rp.id)
let request = provider.createCredentialRegistrationRequest(
challenge: challenge,
name: name,
name: username,
userID: options.publicKey.user.id.data)

requests.append(request)
Expand All @@ -28,8 +28,8 @@ extension SnapAuth {
relyingPartyIdentifier: options.publicKey.rp.id)
let request = provider.createCredentialRegistrationRequest(
challenge: challenge,
displayName: name,
name: name,
displayName: displayName ?? username,
name: username,
userID: options.publicKey.user.id.data)
request.attestationPreference = .direct // TODO: use API response
request.credentialParameters = [.init(algorithm: .ES256)] // TODO: use API response
Expand Down
26 changes: 13 additions & 13 deletions Sources/SnapAuth/SnapAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
/// if the request cannot be fulfilled.
///
/// - Parameters:
/// - name: The name of the user. This should be a username or handle.
/// - username: What the user will use to sign in (often an email address)
/// - displayName: The proper name of the user. If omitted, name will be used.
/// - authenticators: What authenticators should be permitted. If omitted,
/// all available types for the platform will be allowed.
Expand All @@ -98,20 +98,20 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
/// }
/// ```
public func startRegister(
name: String,
username: String,
displayName: String? = nil,
authenticators: Set<Authenticator> = Authenticator.all
) async -> SnapAuthResult {
await startRegister(
name: name,
username: username,
anchor: .default,
displayName: displayName,
authenticators: authenticators)
}

// TODO: Only make this public if needed?
internal func startRegister(
name: String,
username: String,
anchor: ASPresentationAnchor,
displayName: String? = nil,
authenticators: Set<Authenticator> = Authenticator.all
Expand All @@ -131,7 +131,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg

let authRequests = buildRegisterRequests(
from: options,
name: name,
username: username,
displayName: displayName,
authenticators: authenticators)

Expand All @@ -158,7 +158,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
/// if the request cannot be fulfilled.
///
/// - Parameters:
/// - user: The authenticating user's `id` or `handle`
/// - user: The authenticating user's `id` or `username`
/// - authenticators: What authenticators should be permitted. If omitted,
/// all available types for the platform will be allowed.
///
Expand All @@ -169,7 +169,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
/// # Example
/// ```swift
/// Task {
/// let result = await snapAuth.startAuth(.handle("username@example.com"))
/// let result = await snapAuth.startAuth(.username("username@example.com"))
/// switch result {
/// case .success(let auth):
/// // send auth.token to your backend to verify
Expand Down Expand Up @@ -234,15 +234,15 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
public enum AuthenticatingUser {
/// Your application's internal identifier for the user (usually a primary key)
case id(String)
/// The user's handle, such as a username or email address
case handle(String)
/// The user's sign-in handle, such as a username or email address
case username(String)
}

/// Encode as JSON to either `{"id": id}` or `{"handle": handle}`, which is what the SnapAuth APIs need
/// Encode as JSON to either `{"id": id}` or `{"username": username}`, which is what the SnapAuth APIs need
extension AuthenticatingUser: Encodable {
enum CodingKeys: String, CodingKey {
case id
case handle
case username
}

public func encode(to encoder: Encoder) throws {
Expand All @@ -251,8 +251,8 @@ extension AuthenticatingUser: Encodable {
switch self {
case .id(let value):
try container.encode(value, forKey: .id)
case .handle(let value):
try container.encode(value, forKey: .handle)
case .username(let value):
try container.encode(value, forKey: .username)
}
}
}
Expand Down