Skip to content

Commit dd288fb

Browse files
authored
Organization support for passkeys (#973)
1 parent 3c30ba5 commit dd288fb

File tree

3 files changed

+69
-34
lines changed

3 files changed

+69
-34
lines changed

Auth0/Auth0Authentication.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,12 @@ struct Auth0Authentication: Authentication {
210210

211211
#if PASSKEYS_PLATFORM
212212
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
213-
func login(passkey: LoginPasskey,
213+
func login(passkey: any LoginPasskey,
214214
challenge: PasskeyLoginChallenge,
215215
connection: String?,
216216
audience: String?,
217-
scope: String) -> Request<Credentials, AuthenticationError> {
217+
scope: String,
218+
organization: String?) -> Request<Credentials, AuthenticationError> {
218219
let url = URL(string: "oauth/token", relativeTo: self.url)!
219220
let id = passkey.credentialID.encodeBase64URLSafe()
220221

@@ -238,10 +239,10 @@ struct Auth0Authentication: Authentication {
238239
"auth_session": challenge.authenticationSession,
239240
"authn_response": authenticatorResponse
240241
]
241-
242242
payload["realm"] = connection
243243
payload["audience"] = audience
244244
payload["scope"] = includeRequiredScope(in: scope)
245+
payload["organization"] = organization
245246

246247
return Request(session: session,
247248
url: url,
@@ -253,11 +254,13 @@ struct Auth0Authentication: Authentication {
253254
}
254255

255256
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
256-
func passkeyLoginChallenge(connection: String?) -> Request<PasskeyLoginChallenge, AuthenticationError> {
257+
func passkeyLoginChallenge(connection: String?,
258+
organization: String?) -> Request<PasskeyLoginChallenge, AuthenticationError> {
257259
let url = URL(string: "passkey/challenge", relativeTo: self.url)!
258260

259261
var payload: [String: String] = ["client_id": self.clientId]
260262
payload["realm"] = connection
263+
payload["organization"] = organization
261264

262265
return Request(session: session,
263266
url: url,
@@ -269,11 +272,12 @@ struct Auth0Authentication: Authentication {
269272
}
270273

271274
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
272-
func login(passkey: SignupPasskey,
275+
func login(passkey: any SignupPasskey,
273276
challenge: PasskeySignupChallenge,
274277
connection: String?,
275278
audience: String?,
276-
scope: String) -> Request<Credentials, AuthenticationError> {
279+
scope: String,
280+
organization: String?) -> Request<Credentials, AuthenticationError> {
277281
let url = URL(string: "oauth/token", relativeTo: self.url)!
278282
let id = passkey.credentialID.encodeBase64URLSafe()
279283

@@ -299,6 +303,7 @@ struct Auth0Authentication: Authentication {
299303
payload["realm"] = connection
300304
payload["audience"] = audience
301305
payload["scope"] = includeRequiredScope(in: scope)
306+
payload["organization"] = organization
302307

303308
return Request(session: session,
304309
url: url,
@@ -314,7 +319,8 @@ struct Auth0Authentication: Authentication {
314319
phoneNumber: String?,
315320
username: String?,
316321
name: String?,
317-
connection: String?) -> Request<PasskeySignupChallenge, AuthenticationError> {
322+
connection: String?,
323+
organization: String?) -> Request<PasskeySignupChallenge, AuthenticationError> {
318324
let url = URL(string: "passkey/register", relativeTo: self.url)!
319325

320326
var userProfile: [String: Any] = [:]
@@ -328,6 +334,7 @@ struct Auth0Authentication: Authentication {
328334
"user_profile": userProfile
329335
]
330336
payload["realm"] = connection
337+
payload["organization"] = organization
331338

332339
return Request(session: session,
333340
url: url,

Auth0/Authentication.swift

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -529,16 +529,18 @@ public protocol Authentication: Trackable, Loggable {
529529
/// challenge: loginChallenge,
530530
/// connection: "Username-Password-Authentication",
531531
/// audience: "https://example.com/api",
532-
/// scope: "openid profile email offline_access")
532+
/// scope: "openid profile email offline_access",
533+
/// organization: "org_aaAA1aa11aAAAA1a")
533534
/// .start { print($0) }
534535
/// ```
535536
///
536537
/// - Parameters:
537538
/// - passkey: The existing passkey credential obtained from the [`ASAuthorizationControllerDelegate`](https://developer.apple.com/documentation/authenticationservices/asauthorizationcontrollerdelegate) delegate.
538539
/// - challenge: The passkey challenge obtained from ``passkeyLoginChallenge(connection:)``.
539540
/// - connection: Name of the database connection. If a connection name is not specified, your tenant's default directory will be used.
540-
/// - audience: API Identifier that your application is requesting access to. Defaults to `nil`.
541-
/// - scope: Space-separated list of requested scope values. Defaults to `openid profile email`.
541+
/// - audience: API Identifier that your application is requesting access to. Defaults to `nil`.
542+
/// - scope: Space-separated list of requested scope values. Defaults to `openid profile email`.
543+
/// - organization: Identifier of an organization the user is a member of.
542544
/// - Returns: A request that will yield Auth0 user's credentials.
543545
///
544546
/// ## See Also
@@ -551,7 +553,8 @@ public protocol Authentication: Trackable, Loggable {
551553
challenge: PasskeyLoginChallenge,
552554
connection: String?,
553555
audience: String?,
554-
scope: String) -> Request<Credentials, AuthenticationError>
556+
scope: String,
557+
organization: String?) -> Request<Credentials, AuthenticationError>
555558

556559
/// Requests a challenge for logging a user in with an existing passkey. This is the first part of the passkey login flow.
557560
///
@@ -601,7 +604,9 @@ public protocol Authentication: Trackable, Loggable {
601604
/// Then, call ``login(passkey:challenge:connection:audience:scope:)-7s3cz`` with the resulting
602605
/// passkey credential and the challenge to log the user in.
603606
///
604-
/// - Parameter connection: Name of the database connection. If a connection name is not specified, your tenant's default directory will be used.
607+
/// - Parameters:
608+
/// - connection: Name of the database connection. If a connection name is not specified, your tenant's default directory will be used.
609+
/// - organization: Identifier of an organization the user is a member of.
605610
/// - Returns: A request that will yield a passkey login challenge.
606611
///
607612
/// ## See Also
@@ -610,7 +615,8 @@ public protocol Authentication: Trackable, Loggable {
610615
/// - [Native Passkeys for Mobile Applications](https://auth0.com/docs/native-passkeys-for-mobile-applications)
611616
/// - [Supporting passkeys](https://developer.apple.com/documentation/authenticationservices/supporting-passkeys#Connect-to-a-service-with-an-existing-account)
612617
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
613-
func passkeyLoginChallenge(connection: String?) -> Request<PasskeyLoginChallenge, AuthenticationError>
618+
func passkeyLoginChallenge(connection: String?,
619+
organization: String?) -> Request<PasskeyLoginChallenge, AuthenticationError>
614620

615621
/// Logs a new user in using a signup passkey credential and the signup challenge. This is the last part of the passkey signup flow.
616622
///
@@ -647,7 +653,8 @@ public protocol Authentication: Trackable, Loggable {
647653
/// challenge: signupChallenge,
648654
/// connection: "Username-Password-Authentication",
649655
/// audience: "https://example.com/api",
650-
/// scope: "openid profile email offline_access")
656+
/// scope: "openid profile email offline_access",
657+
/// organization: "org_aaAA1aa11aAAAA1a")
651658
/// .start { print($0) }
652659
/// ```
653660
///
@@ -657,6 +664,7 @@ public protocol Authentication: Trackable, Loggable {
657664
/// - connection: Name of the database connection where the user will be created. If a connection name is not specified, your tenant's default directory will be used.
658665
/// - audience: API Identifier that your application is requesting access to. Defaults to `nil`.
659666
/// - scope: Space-separated list of requested scope values. Defaults to `openid profile email`.
667+
/// - organization: Identifier of an organization the user is a member of.
660668
/// - Returns: A request that will yield Auth0 user's credentials.
661669
///
662670
/// ## See Also
@@ -669,7 +677,8 @@ public protocol Authentication: Trackable, Loggable {
669677
challenge: PasskeySignupChallenge,
670678
connection: String?,
671679
audience: String?,
672-
scope: String) -> Request<Credentials, AuthenticationError>
680+
scope: String,
681+
organization: String?) -> Request<Credentials, AuthenticationError>
673682

674683
/// Requests a challenge for registering a new user with a passkey. This is the first part of the passkey signup flow.
675684
///
@@ -694,7 +703,8 @@ public protocol Authentication: Trackable, Loggable {
694703
/// .authentication()
695704
/// .passkeySignupChallenge(email: "support@auth0.com",
696705
/// name: "John Appleseed",
697-
/// connection: "Username-Password-Authentication")
706+
/// connection: "Username-Password-Authentication",
707+
/// organization: "org_aaAA1aa11aAAAA1a")
698708
/// .start { result in
699709
/// switch result {
700710
/// case .success(let signupChallenge):
@@ -736,6 +746,7 @@ public protocol Authentication: Trackable, Loggable {
736746
/// - username: Username of the user. Defaults to `nil`.
737747
/// - name: Display name of the user. Defaults to `nil`.
738748
/// - connection: Name of the database connection where the user will be created. If a connection name is not specified, your tenant's default directory will be used.
749+
/// - organization: Identifier of an organization the user is a member of.
739750
/// - Returns: A request that will yield a passkey signup challenge.
740751
///
741752
/// ## See Also
@@ -748,7 +759,8 @@ public protocol Authentication: Trackable, Loggable {
748759
phoneNumber: String?,
749760
username: String?,
750761
name: String?,
751-
connection: String?) -> Request<PasskeySignupChallenge, AuthenticationError>
762+
connection: String?,
763+
organization: String?) -> Request<PasskeySignupChallenge, AuthenticationError>
752764
#endif
753765

754766
/**
@@ -1114,43 +1126,49 @@ public extension Authentication {
11141126
challenge: PasskeyLoginChallenge,
11151127
connection: String? = nil,
11161128
audience: String? = nil,
1117-
scope: String = defaultScope) -> Request<Credentials, AuthenticationError> {
1129+
scope: String = defaultScope,
1130+
organization: String? = nil) -> Request<Credentials, AuthenticationError> {
11181131
return self.login(passkey: passkey,
11191132
challenge: challenge,
11201133
connection: connection,
11211134
audience: audience,
1122-
scope: scope)
1135+
scope: scope,
1136+
organization: organization)
11231137
}
11241138

11251139
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
1126-
func passkeyLoginChallenge(connection: String? = nil) -> Request<PasskeyLoginChallenge, AuthenticationError> {
1127-
return self.passkeyLoginChallenge(connection: connection)
1140+
func passkeyLoginChallenge(connection: String? = nil, organization: String? = nil) -> Request<PasskeyLoginChallenge, AuthenticationError> {
1141+
return self.passkeyLoginChallenge(connection: connection, organization: organization)
11281142
}
11291143

11301144
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
11311145
func login(passkey: SignupPasskey,
11321146
challenge: PasskeySignupChallenge,
11331147
connection: String? = nil,
11341148
audience: String? = nil,
1135-
scope: String = defaultScope) -> Request<Credentials, AuthenticationError> {
1149+
scope: String = defaultScope,
1150+
organization: String? = nil) -> Request<Credentials, AuthenticationError> {
11361151
return self.login(passkey: passkey,
11371152
challenge: challenge,
11381153
connection: connection,
11391154
audience: audience,
1140-
scope: scope)
1155+
scope: scope,
1156+
organization: organization)
11411157
}
11421158

11431159
@available(iOS 16.6, macOS 13.5, visionOS 1.0, *)
11441160
func passkeySignupChallenge(email: String? = nil,
11451161
phoneNumber: String? = nil,
11461162
username: String? = nil,
11471163
name: String? = nil,
1148-
connection: String? = nil) -> Request<PasskeySignupChallenge, AuthenticationError> {
1164+
connection: String? = nil,
1165+
organization: String? = nil) -> Request<PasskeySignupChallenge, AuthenticationError> {
11491166
return self.passkeySignupChallenge(email: email,
11501167
phoneNumber: phoneNumber,
11511168
username: username,
11521169
name: name,
1153-
connection: connection)
1170+
connection: connection,
1171+
organization: organization)
11541172
}
11551173
#endif
11561174

0 commit comments

Comments
 (0)