Files
self/packages/native-shell-ios/Sources/SelfNativeShell/API/SelfSdkConfig.swift
Justin Hernandez f29130587b Harden WebView bridge and asset serving across native shells (#1924)
* security fix

* more security fixes

* fixes

* pr feedback

* Restore remote URL loading in native-shell-ios and native-shell-android

Remove bundled-asset-only loading and SHA-256 integrity checks from both
native shell packages. WebViews now load directly from the remote URL
(default: https://self-app-alpha.vercel.app) over HTTPS, matching the
pattern already implemented in kmp-sdk and self-sdk-swift.

Also fixes ObjC selector mismatch in self-sdk-swift WebViewProviderImpl
for configureRemoteLoading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Restore remote URL loading in kmp-sdk and self-sdk-swift

Remove bundled-asset-only loading from kmp-sdk AndroidWebViewHost and
self-sdk-swift WebViewProviderImpl. Both now load directly from the
remote URL (default: https://self-app-alpha.vercel.app) over HTTPS.

Adds remoteWebAppBaseUrl to SelfSdkConfig and pipes it through
IosWebViewHost via the new configureRemoteLoading protocol method.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* coderabbit comments

* lint

* coderabbit comments

---------

Co-authored-by: seshanthS <seshanth@protonmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 22:39:27 +05:30

116 lines
4.2 KiB
Swift

// SPDX-License-Identifier: BUSL-1.1
import Foundation
public struct SelfSdkConfig {
public let verificationId: String
public let userId: String
public let environment: String
public let isDebugMode: Bool
public let version: Int
public let scope: String?
public let disclosures: [String]?
public let appName: String?
public let appEndpoint: String?
public let resultType: String?
public let excludedCountries: [String]?
public let endpointType: String?
public let userIdType: String?
public let chainID: Int?
public let userDefinedData: String?
public let selfDefinedData: String?
public let remoteWebAppBaseURL: URL?
public let secureStorageProvider: SecureStorageProvider
public init(
verificationId: String,
userId: String,
environment: String = "prod",
isDebugMode: Bool = false,
version: Int = 1,
scope: String? = nil,
disclosures: [String]? = nil,
appName: String? = nil,
appEndpoint: String? = nil,
resultType: String? = nil,
excludedCountries: [String]? = nil,
endpointType: String? = nil,
userIdType: String? = nil,
chainID: Int? = nil,
userDefinedData: String? = nil,
selfDefinedData: String? = nil,
remoteWebAppBaseURL: URL? = nil,
secureStorageProvider: SecureStorageProvider
) {
self.verificationId = verificationId
self.userId = userId
self.environment = environment
self.isDebugMode = isDebugMode
self.version = version
self.scope = scope
self.disclosures = disclosures
self.appName = appName
self.appEndpoint = appEndpoint
self.resultType = resultType
self.excludedCountries = excludedCountries
self.endpointType = endpointType
self.userIdType = userIdType
self.chainID = chainID
self.userDefinedData = userDefinedData
self.selfDefinedData = selfDefinedData
self.remoteWebAppBaseURL = remoteWebAppBaseURL
self.secureStorageProvider = secureStorageProvider
}
func toQueryParams() -> String {
var components = URLComponents()
var items = [
URLQueryItem(name: "environment", value: environment),
URLQueryItem(name: "verificationId", value: verificationId),
URLQueryItem(name: "userId", value: userId),
URLQueryItem(name: "version", value: String(version))
]
if let scope = scope {
items.append(URLQueryItem(name: "scope", value: scope))
}
if let disclosures = disclosures, !disclosures.isEmpty {
items.append(URLQueryItem(name: "disclosures", value: disclosures.joined(separator: ",")))
}
if let appName = appName {
items.append(URLQueryItem(name: "appName", value: appName))
}
if let appEndpoint = appEndpoint {
items.append(URLQueryItem(name: "appEndpoint", value: appEndpoint))
}
if let resultType = resultType {
items.append(URLQueryItem(name: "resultType", value: resultType))
}
if let excludedCountries = excludedCountries, !excludedCountries.isEmpty {
items.append(URLQueryItem(name: "excludedCountries", value: excludedCountries.joined(separator: ",")))
}
if let endpointType = endpointType {
items.append(URLQueryItem(name: "endpointType", value: endpointType))
}
if let userIdType = userIdType {
items.append(URLQueryItem(name: "userIdType", value: userIdType))
}
if let chainID = chainID {
items.append(URLQueryItem(name: "chainID", value: String(chainID)))
}
if let userDefinedData = userDefinedData {
items.append(URLQueryItem(name: "userDefinedData", value: userDefinedData))
}
if let selfDefinedData = selfDefinedData {
items.append(URLQueryItem(name: "selfDefinedData", value: selfDefinedData))
}
components.queryItems = items
return components.percentEncodedQuery ?? ""
}
}
public protocol SelfSdkCallback: AnyObject {
func onSuccess(result: [String: Any])
func onFailure(error: Error)
func onCancelled()
}