Skip to content

Commit 5a571d2

Browse files
authored
Telemetry implemented (#29)
* Telemetry implemented * Fixed testcase bugs * Updated Telemetry implementation to match the product requirements for Beta * Updated Agents.md file and removed unused function & updated tests accordingly * Updated AGENTS.md lint enforcement rule since it would have had no effect
1 parent 605cefd commit 5a571d2

32 files changed

Lines changed: 320 additions & 92 deletions

AGENTS.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,39 @@ This SDK uses **Universal Login** for MFA step-up flows. When an MFA-required er
143143

144144
See [Auth0.swift documentation](https://github.com/auth0/Auth0.swift) for detailed setup.
145145

146+
## MyAccount API Client — Required Pattern
147+
148+
**All My Account API calls MUST use `MyAccountClientFactory.create()` instead of calling `Auth0.myAccount()` directly.**
149+
150+
This factory attaches the `Auth0-Client` HTTP header that identifies requests as originating from the UI Components SDK. The library name and version are defined centrally in `Auth0UniversalComponents/Version.swift`:
151+
152+
```swift
153+
// Version.swift
154+
let version = "1.0.0"
155+
let libraryName = "universal-components-ios"
156+
```
157+
158+
### Correct Usage
159+
160+
```swift
161+
// In any UseCase
162+
let client = MyAccountClientFactory.create(
163+
token: apiCredentials.accessToken,
164+
domain: dependencies.domain,
165+
session: session
166+
)
167+
let result = try await client.authenticationMethods.enrollTOTP().start()
168+
```
169+
170+
### Incorrect Usage (will trigger SwiftLint error)
171+
172+
```swift
173+
// DO NOT use Auth0.myAccount() directly — this bypasses telemetry headers
174+
let client = Auth0.myAccount(token: token, domain: domain, session: session)
175+
```
176+
177+
---
178+
146179
## Key Technical Decisions
147180

148181
### UI Framework Support

Auth0UniversalComponents/Auth0UniversalComponentsSDKInitializer.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,6 @@ public actor Auth0UniversalComponentsSDKInitializer {
142142
tokenProvider: tokenProvider)
143143
}
144144

145-
/// Reset the SDK to an uninitialized state.
146-
///
147-
/// This is primarily used for testing purposes to clear the singleton instance.
148-
static func reset() {
149-
_shared = nil
150-
}
151145
}
152146

153147
/// Ensures a URL string has an HTTPS scheme.

Auth0UniversalComponents/AuthMethodsHome/Domain/GetAuthMethodsUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct GetAuthMethodsUseCase: GetAuthMethodsUseCaseable {
4545
/// - Returns: Array of enrolled authentication methods
4646
/// - Throws: Auth0APIError if the request fails
4747
func execute(request: GetAuthMethodsRequest) async throws -> [AuthenticationMethod] {
48-
try await Auth0.myAccount(token: request.token, domain: request.domain, session: session)
48+
try await MyAccountClientFactory.create(token: request.token, domain: request.domain, session: session)
4949
.authenticationMethods
5050
.getAuthenticationMethods()
5151
.start()

Auth0UniversalComponents/AuthMethodsHome/Domain/GetFactorsUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct GetFactorsUseCase: GetFactorsUseCaseable {
4545
/// - Returns: Array of available authentication factors
4646
/// - Throws: Auth0APIError if the request fails
4747
func execute(request: GetFactorsRequest) async throws -> [Factor] {
48-
try await Auth0.myAccount(token: request.token, domain: request.domain, session: session)
48+
try await MyAccountClientFactory.create(token: request.token, domain: request.domain, session: session)
4949
.authenticationMethods
5050
.getFactors()
5151
.start()

Auth0UniversalComponents/AuthMethodsHome/Presentation/MyAccountAuthMethodsViewModel.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Combine
2+
import Foundation
23
import SwiftUI
34
import Auth0
45

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Auth0
2+
import Foundation
3+
4+
/// Factory for creating MyAccount API clients with telemetry pre-applied.
5+
///
6+
/// All UseCases should use this factory instead of calling `Auth0.myAccount()` directly.
7+
/// This ensures the `Auth0-Client` header identifies requests as originating from
8+
/// the UI Components SDK.
9+
struct MyAccountClientFactory {
10+
static func create(token: String, domain: String, session: URLSession = .shared) -> MyAccount {
11+
var client = Auth0.myAccount(token: token, domain: domain, session: session)
12+
client.using(inLibrary: libraryName, version: version)
13+
return client
14+
}
15+
16+
static func create(token: String, domain: String) -> MyAccount {
17+
var client = Auth0.myAccount(token: token, domain: domain)
18+
client.using(inLibrary: libraryName, version: version)
19+
return client
20+
}
21+
}

Auth0UniversalComponents/Core/Utils/ErrorHandler.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,5 @@ struct ErrorHandler {
197197
retryCallback()
198198
}
199199
}
200+
200201
}

Auth0UniversalComponents/EmailSMSEnrollment/Domain/ConfirmEmailEnrollmentUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct ConfirmEmailEnrollmentUseCase: ConfirmEmailEnrollmentUseCaseable {
6161
/// - Returns: The newly created email authentication method
6262
/// - Throws: Auth0APIError if the OTP is invalid or the request fails
6363
func execute(request: ConfirmEmailEnrollmentRequest) async throws -> AuthenticationMethod {
64-
try await Auth0.myAccount(token: request.token, domain: request.domain, session: session)
64+
try await MyAccountClientFactory.create(token: request.token, domain: request.domain, session: session)
6565
.authenticationMethods
6666
.confirmEmailEnrollment(id: request.id, authSession: request.authSession, otpCode: request.otpCode)
6767
.start()

Auth0UniversalComponents/EmailSMSEnrollment/Domain/ConfirmPhoneEnrollmentUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct ConfirmPhoneEnrollmentUseCase: ConfirmPhoneEnrollmentUseCaseable {
6161
/// - Returns: The newly created phone authentication method
6262
/// - Throws: Auth0APIError if the OTP is invalid or the request fails
6363
func execute(request: ConfirmPhoneEnrollmentRequest) async throws -> AuthenticationMethod {
64-
try await Auth0.myAccount(token: request.token, domain: request.domain, session: session)
64+
try await MyAccountClientFactory.create(token: request.token, domain: request.domain, session: session)
6565
.authenticationMethods
6666
.confirmPhoneEnrollment(id: request.id, authSession: request.authSession, otpCode: request.otpCode)
6767
.start()

Auth0UniversalComponents/EmailSMSEnrollment/Domain/StartEmailEnrollmentUseCase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct StartEmailEnrollmentUseCase: StartEmailEnrollmentUseCaseable {
5353
/// - Returns: Email enrollment challenge with verification details
5454
/// - Throws: Auth0APIError if the request fails
5555
func execute(request: StartEmailEnrollmentRequest) async throws -> EmailEnrollmentChallenge {
56-
try await Auth0.myAccount(token: request.token, domain: request.domain, session: session)
56+
try await MyAccountClientFactory.create(token: request.token, domain: request.domain, session: session)
5757
.authenticationMethods
5858
.enrollEmail(emailAddress: request.email)
5959
.start()

0 commit comments

Comments
 (0)