Add the SuperTokens lazy user migration flow#124
Conversation
Reviewer's GuideAdds SuperTokens lazy user migration support by extending Rownd configuration with SuperTokens metadata, registering a SuperTokens-specific Rownd event handler during configuration, and performing a one-time migration call to the SuperTokens migrate endpoint for newly created users after sign-in completes. Sequence diagram for SuperTokens lazy user migration on sign-insequenceDiagram
actor User
participant iOSApp
participant RowndSDK
participant ContextEventBus
participant SuperTokensSyncEventHandler
participant RowndAuth
participant SuperTokensAPI
User->>iOSApp: Initiate_sign_in
iOSApp->>RowndSDK: Rownd.signIn
RowndSDK-->>RowndSDK: Authenticate_user
RowndSDK-->>ContextEventBus: Emit_RowndEvent(signInCompleted,\nuser_type=new_user)
ContextEventBus-->>SuperTokensSyncEventHandler: Dispatch_RowndEvent
SuperTokensSyncEventHandler-->>SuperTokensSyncEventHandler: Validate_event
Note over SuperTokensSyncEventHandler: Checks event_type == signInCompleted\nand user_type == new_user and Rownd.config.supertokens.appInfo != nil
SuperTokensSyncEventHandler->>RowndAuth: Rownd.getAccessToken()
RowndAuth-->>SuperTokensSyncEventHandler: accessToken
SuperTokensSyncEventHandler->>SuperTokensAPI: POST /plugin/rownd/migrate\nAuthorization: Bearer_accessToken\nBase: apiDomain + apiBasePath
SuperTokensAPI-->>SuperTokensSyncEventHandler: 2xx_on_success_or_error_status
SuperTokensSyncEventHandler-->>SuperTokensSyncEventHandler: Log_result_and_return
Updated class diagram for Rownd SuperTokens configuration and syncclassDiagram
class SuperTokensAppInfo {
+String appName
+String apiDomain
+String apiBasePath
+init(appName: String, apiDomain: String, apiBasePath: String)
}
class SuperTokensConfig {
+SuperTokensAppInfo appInfo
+init(appInfo: SuperTokensAppInfo)
}
class RowndConfig {
+SuperTokensConfig supertokens
+String appKey
+String appGroupPrefix
+Bool enableSmartLinkPasteBehavior
+String signInLinkPattern
}
class Rownd {
+static RowndConfig config
+static func configure(config: RowndConfig)
+static func getAccessToken() async throws String
}
class RowndEvent {
+RowndEventType event
+Dictionary data
}
class RowndEventHandlerDelegate {
<<protocol>>
+func handleRowndEvent(event: RowndEvent)
}
class Context {
+static Context currentContext
+Array eventListeners
}
class SuperTokensSyncEventHandler {
-OSLog log
+func handleRowndEvent(event: RowndEvent)
}
class SuperTokensSyncModule {
+static func registerSuperTokensSyncEventHandler()
+static func syncUserToSuperTokens(accessToken: String, appInfo: SuperTokensAppInfo) async
}
RowndConfig --> SuperTokensConfig : has_optional
SuperTokensConfig --> SuperTokensAppInfo : has
SuperTokensSyncEventHandler ..|> RowndEventHandlerDelegate : implements
SuperTokensSyncEventHandler --> SuperTokensAppInfo : reads
SuperTokensSyncEventHandler --> Rownd : uses
SuperTokensSyncEventHandler --> RowndEvent : handles
SuperTokensSyncModule --> SuperTokensSyncEventHandler : manages_singleton
SuperTokensSyncModule --> Context : registers_listener
SuperTokensSyncModule --> SuperTokensAppInfo : builds_endpoint
SuperTokensSyncModule --> Rownd : uses_access_token
Rownd --> RowndConfig : uses_config
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Review Summary by QodoAdd SuperTokens lazy user migration flow
WalkthroughsDescription• Adds SuperTokens lazy user migration support to iOS SDK • Implements automatic user sync on new sign-in completion • Sends Rownd access token to SuperTokens migration endpoint • Registers event handler during SDK configuration Diagramflowchart LR
A["Rownd.configure"] --> B["registerSuperTokensSyncEventHandler"]
B --> C["SuperTokensSyncEventHandler registered"]
D["signInCompleted event"] --> E["Check if new_user"]
E --> F["Get Rownd accessToken"]
F --> G["POST to SuperTokens migrate endpoint"]
G --> H["User synced to SuperTokens"]
File Changes1. Sources/Rownd/Models/RowndConfig.swift
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
syncUserToSuperTokens, avoid force-unwrapping the URL (i.e.,URL(string: ...)!) and instead gracefully handle an invalidapiDomain/apiBasePathby safely constructing the URL and logging an error if it fails. - Given
RowndConfigisEncodableandsupertokensis added under the "These will not be encoded" section, double-check that the coding keys or custom encoding logic actually excludesupertokensthe same way as the other non-encoded properties.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `syncUserToSuperTokens`, avoid force-unwrapping the URL (i.e., `URL(string: ...)!`) and instead gracefully handle an invalid `apiDomain`/`apiBasePath` by safely constructing the URL and logging an error if it fails.
- Given `RowndConfig` is `Encodable` and `supertokens` is added under the "These will not be encoded" section, double-check that the coding keys or custom encoding logic actually exclude `supertokens` the same way as the other non-encoded properties.
## Individual Comments
### Comment 1
<location path="Sources/Rownd/framework/SuperTokensSync.swift" line_range="54" />
<code_context>
+ let base = "\(appInfo.apiDomain)\(appInfo.apiBasePath)"
+
+ do {
+ var request = URLRequest(url: URL(string: "\(base)/plugin/rownd/migrate")!)
+ request.httpMethod = "POST"
+ request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
</code_context>
<issue_to_address>
**issue (bug_risk):** Force-unwrapping the SuperTokens migration URL can crash on misconfiguration.
Because this URL is built from external config, `URL(string: ...)!` can crash the app if `apiDomain`/`apiBasePath` are malformed (missing scheme, extra slashes, spaces, etc.). Consider safely handling failures:
```swift
let base = "\(appInfo.apiDomain)\(appInfo.apiBasePath)"
guard let url = URL(string: "\(base)/plugin/rownd/migrate") else {
log.error("[Rownd->ST] invalid migration URL constructed from base: \(base)")
return
}
var request = URLRequest(url: url)
```
This prevents a crash while still exposing the misconfiguration via logs.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
9409768 to
f560aad
Compare
Summary
Adds SuperTokens lazy user migration support to the iOS SDK.
When the SuperTokens config is included and a Rownd sign-in completes for a
new_user, the SDK now calls the the${apiBasePath}/plugin/rownd/migrateendpoint.SuperTokensAppInfoandSuperTokensConfigtoRowndConfigRownd.configure(...)signInCompletedand only triggers migration fornew_user${apiBasePath}/plugin/rownd/migrateThe main SDK behavior lives in:
Sources/Rownd/Models/RowndConfig.swiftSources/Rownd/Rownd.swiftSources/Rownd/framework/SuperTokensSync.swiftSummary by Sourcery
Add support for lazily migrating newly created Rownd users to SuperTokens in the iOS SDK.
New Features: