From 8497a4238bb436543fc30dab7defd82a0febbc2a Mon Sep 17 00:00:00 2001 From: Itai Hanski Date: Thu, 15 Jan 2026 12:23:17 +0200 Subject: [PATCH 1/7] Update iOS SDK to 0.10.5 and Android SDK to 0.18.0 --- android/build.gradle | 2 +- .../descope-swift-sdk/flows/Flow.swift | 20 ++++++++++++ .../descope-swift-sdk/flows/FlowBridge.swift | 31 ++++++++++++++----- ios/Classes/descope-swift-sdk/sdk/SDK.swift | 2 +- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 74115026..3b893fa0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -51,7 +51,7 @@ android { implementation "androidx.browser:browser:1.8.0" implementation "androidx.security:security-crypto:1.1.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2" - implementation "com.descope:descope-kotlin:0.17.9" + implementation "com.descope:descope-kotlin:0.18.0" } testOptions { diff --git a/ios/Classes/descope-swift-sdk/flows/Flow.swift b/ios/Classes/descope-swift-sdk/flows/Flow.swift index ec0636e4..dcc942ab 100644 --- a/ios/Classes/descope-swift-sdk/flows/Flow.swift +++ b/ios/Classes/descope-swift-sdk/flows/Flow.swift @@ -170,3 +170,23 @@ extension DescopeFlow: CustomStringConvertible { return "DescopeFlow(url: \"\(url)\")" } } + +/// Convenience constructor when use Descope's Flow hosting service +extension DescopeFlow { + /// Creates a new ``DescopeFlow`` object that encapsulates a single flow run. + /// + /// - Important: This method of creating a ``DescopeFlow`` is only applicable when + /// using Descope's Flow hosting service. If you host your own flows, use the + /// default initializer instead. + /// + /// - Parameters: + /// - flowId: The ID of the flow + /// - descope: An optional ``DescopeSDK`` to use instead of the ``Descope`` singleton. + public convenience init(flowId: String, descope: DescopeSDK? = nil) { + let sdk = descope ?? Descope.sdk + precondition(!sdk.config.projectId.isEmpty, "The Descope SDK must be initialized before use") + let url = "\(sdk.client.baseURL)/login/\(sdk.client.config.projectId)?mobile=true&flow=\(flowId)" + self.init(url: url) + self.descope = descope + } +} diff --git a/ios/Classes/descope-swift-sdk/flows/FlowBridge.swift b/ios/Classes/descope-swift-sdk/flows/FlowBridge.swift index 903296bc..18b5ae28 100644 --- a/ios/Classes/descope-swift-sdk/flows/FlowBridge.swift +++ b/ios/Classes/descope-swift-sdk/flows/FlowBridge.swift @@ -186,7 +186,15 @@ extension FlowBridge { if tag == "fail" { logger.error("Bridge encountered script error in webpage", message) } else if logger.isUnsafeEnabled { - logger.debug("Webview console.\(tag): \(message)") + let logMessage = "Webview console.\(tag): \(message)" + switch tag { + case "error": + logger.error(logMessage) + case "warn", "info", "log": + logger.info(logMessage) + default: + logger.debug(logMessage) + } } case .found: logger.info("Bridge received found event") @@ -438,12 +446,21 @@ private struct FlowNativeOptions: Encodable { /// Redirects errors and console logs to the bridge private let loggingScript = """ -window.onerror = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'fail', message: s }) } -window.console.error = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'error', message: s }) } -window.console.warn = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'warn', message: s }) } -window.console.info = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'info', message: s }) } -window.console.debug = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'debug', message: s }) } -window.console.log = (s) => { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'log', message: s }) } +(function() { + function stringify(args) { + return Array.from(args).map(arg => { + if (!arg) return "" + if (typeof arg === 'string') return arg + return JSON.stringify(arg) + }).join(' ') + } + window.onerror = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'fail', message: stringify(arguments) }) }; + window.console.error = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'error', message: stringify(arguments) }) }; + window.console.warn = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'warn', message: stringify(arguments) }) }; + window.console.info = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'info', message: stringify(arguments) }) }; + window.console.debug = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'debug', message: stringify(arguments) }) }; + window.console.log = function() { window.webkit.messageHandlers.\(FlowBridgeMessage.log.rawValue).postMessage({ tag: 'log', message: stringify(arguments) }) }; +})(); """ diff --git a/ios/Classes/descope-swift-sdk/sdk/SDK.swift b/ios/Classes/descope-swift-sdk/sdk/SDK.swift index 9532c051..c68572dc 100644 --- a/ios/Classes/descope-swift-sdk/sdk/SDK.swift +++ b/ios/Classes/descope-swift-sdk/sdk/SDK.swift @@ -143,7 +143,7 @@ public extension DescopeSDK { static let name = "DescopeKit" /// The Descope SDK version - static let version = "0.10.4" + static let version = "0.10.5" } // Internal From 3ff2dde4443147572013a2d729e491e3d9819525 Mon Sep 17 00:00:00 2001 From: Itai Hanski Date: Thu, 15 Jan 2026 12:36:24 +0200 Subject: [PATCH 2/7] Implement log streaming from native layer --- .../com/descope/flutter/DescopePlugin.kt | 67 ++++++++++++++++ ios/Classes/DescopePlugin.swift | 68 ++++++++++++++++ .../internal/others/native_log_bridge.dart | 4 + .../others/native_log_bridge_native.dart | 80 +++++++++++++++++++ .../others/native_log_bridge_unsupported.dart | 16 ++++ lib/src/sdk/config.dart | 50 ++++++++++-- lib/src/sdk/sdk.dart | 3 + 7 files changed, 280 insertions(+), 8 deletions(-) create mode 100644 lib/src/internal/others/native_log_bridge.dart create mode 100644 lib/src/internal/others/native_log_bridge_native.dart create mode 100644 lib/src/internal/others/native_log_bridge_unsupported.dart diff --git a/android/src/main/kotlin/com/descope/flutter/DescopePlugin.kt b/android/src/main/kotlin/com/descope/flutter/DescopePlugin.kt index 6fdaa2c6..3d2e6cff 100644 --- a/android/src/main/kotlin/com/descope/flutter/DescopePlugin.kt +++ b/android/src/main/kotlin/com/descope/flutter/DescopePlugin.kt @@ -2,14 +2,18 @@ package com.descope.flutter import android.content.Context import android.net.Uri +import android.os.Handler +import android.os.Looper import androidx.browser.customtabs.CustomTabsIntent import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKeys +import com.descope.Descope import com.descope.android.DescopeSystemInfo import com.descope.internal.routes.getPackageOrigin import com.descope.internal.routes.performAssertion import com.descope.internal.routes.performNativeAuthorization import com.descope.internal.routes.performRegister +import com.descope.sdk.DescopeLogger import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding @@ -25,6 +29,7 @@ import kotlinx.coroutines.launch /** DescopePlugin */ class DescopePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { private var channel : MethodChannel? = null + private var logChannel: MethodChannel? = null private var context: Context? = null private lateinit var storage: Store @@ -180,6 +185,38 @@ class DescopePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "descope_flutter/methods") channel?.setMethodCallHandler(this) + // Set up the log channel with a handler for logger configuration from Flutter + val logsChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "descope_flutter/logs") + logChannel = logsChannel + val applicationContext = flutterPluginBinding.applicationContext + + logsChannel.setMethodCallHandler { call, result -> + if (call.method == "configure") { + val levelString = call.argument("level") + val unsafe = call.argument("unsafe") + + if (levelString == null || unsafe == null) { + result.error("INVALID_ARGS", "Missing level or unsafe arguments", null) + return@setMethodCallHandler + } + + val level = when (levelString) { + "error" -> DescopeLogger.Level.Error + "info" -> DescopeLogger.Level.Info + else -> DescopeLogger.Level.Debug + } + + // Initialize SDK with the logger configured from Flutter + Descope.setup(applicationContext, projectId = "") { + logger = FlutterDescopeLogger(logsChannel, level, unsafe) + } + + result.success(null) + } else { + result.notImplemented() + } + } + flutterPluginBinding.platformViewRegistry.registerViewFactory( "descope_flutter/descope_flow_view", DescopeFlowViewFactory(flutterPluginBinding.binaryMessenger) @@ -189,6 +226,8 @@ class DescopePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel?.setMethodCallHandler(null) channel = null + logChannel?.setMethodCallHandler(null) + logChannel = null } // ActivityAware @@ -272,3 +311,31 @@ private fun createEncryptedStore(context: Context, projectId: String): Store { } } } + +// Logger + +/** + * A DescopeLogger subclass that forwards all logs to Flutter via a MethodChannel. + * This logger mirrors the level and unsafe settings from the Flutter layer. + */ +private class FlutterDescopeLogger(private val channel: MethodChannel, level: Level, unsafe: Boolean) : DescopeLogger(level, unsafe) { + private val handler = Handler(Looper.getMainLooper()) + + override fun output(level: Level, message: String, values: List) { + val levelString = when (level) { + Level.Error -> "error" + Level.Info -> "info" + Level.Debug -> "debug" + } + + val valuesArray = values.map { it.toString() } + + handler.post { + channel.invokeMethod("log", mapOf( + "level" to levelString, + "message" to message, + "values" to valuesArray, + )) + } + } +} diff --git a/ios/Classes/DescopePlugin.swift b/ios/Classes/DescopePlugin.swift index 29506d56..684dba73 100644 --- a/ios/Classes/DescopePlugin.swift +++ b/ios/Classes/DescopePlugin.swift @@ -14,9 +14,44 @@ public class DescopePlugin: NSObject, FlutterPlugin, FlutterStreamHandler { public static func register(with registrar: FlutterPluginRegistrar) { let methodChannel = FlutterMethodChannel(name: "descope_flutter/methods", binaryMessenger: registrar.messenger()) let eventChannel = FlutterEventChannel(name: "descope_flutter/events", binaryMessenger: registrar.messenger()) + let logChannel = FlutterMethodChannel(name: "descope_flutter/logs", binaryMessenger: registrar.messenger()) let instance = DescopePlugin() + // Set up log channel handler for logger configuration from Flutter + logChannel.setMethodCallHandler { call, result in + if call.method == "configure" { + guard let args = call.arguments as? [String: Any], + let levelString = args["level"] as? String, + let unsafe = args["unsafe"] as? Bool else { + result(FlutterError(code: "INVALID_ARGS", message: "Missing level or unsafe arguments", details: nil)) + return + } + + let level: DescopeLogger.Level + switch levelString { + case "error": + level = .error + case "info": + level = .info + default: + level = .debug + } + + // Initialize SDK with the logger configured from Flutter + // Descope.setup is @MainActor so we ensure we're on the main thread + DispatchQueue.main.async { + Descope.setup(projectId: "") { config in + config.logger = FlutterDescopeLogger(channel: logChannel, level: level, unsafe: unsafe) + } + } + + result(nil) + } else { + result(FlutterMethodNotImplemented) + } + } + eventChannel.setStreamHandler(instance) registrar.addMethodCallDelegate(instance, channel: methodChannel) @@ -306,3 +341,36 @@ extension FlutterError { self.init(code: code, message: message, details: nil) } } + +/// A DescopeLogger subclass that forwards all logs to Flutter via a MethodChannel. +/// This logger is configured with the level and unsafe settings from the Flutter layer. +private class FlutterDescopeLogger: DescopeLogger { + private let channel: FlutterMethodChannel + + init(channel: FlutterMethodChannel, level: Level, unsafe: Bool) { + self.channel = channel + super.init(level: level, unsafe: unsafe) + } + + override func output(level: Level, message: String, unsafe values: [Any]) { + let levelString: String + switch level { + case .error: + levelString = "error" + case .info: + levelString = "info" + case .debug: + levelString = "debug" + } + + let valuesArray = values.map { String(describing: $0) } + + DispatchQueue.main.async { + self.channel.invokeMethod("log", arguments: [ + "level": levelString, + "message": message, + "values": valuesArray, + ]) + } + } +} diff --git a/lib/src/internal/others/native_log_bridge.dart b/lib/src/internal/others/native_log_bridge.dart new file mode 100644 index 00000000..769120e0 --- /dev/null +++ b/lib/src/internal/others/native_log_bridge.dart @@ -0,0 +1,4 @@ +// Native log bridging is only available on iOS and Android. +// On other platforms, a no-op stub will be used. +export 'native_log_bridge_unsupported.dart' if (dart.library.io) 'native_log_bridge_native.dart'; + diff --git a/lib/src/internal/others/native_log_bridge_native.dart b/lib/src/internal/others/native_log_bridge_native.dart new file mode 100644 index 00000000..7ad17124 --- /dev/null +++ b/lib/src/internal/others/native_log_bridge_native.dart @@ -0,0 +1,80 @@ +import 'package:flutter/services.dart'; + +import '/src/sdk/config.dart'; + +/// Bridges log streaming from native SDK layers (iOS/Android) to Flutter. +/// +/// This class listens on the `descope_flutter/logs` MethodChannel and forwards +/// received native logs to the Flutter DescopeLogger, which filters based on +/// its own `level` and `unsafe` settings. +class NativeLogBridge { + static const _logChannel = MethodChannel('descope_flutter/logs'); + static DescopeLogger? _logger; + static bool _isInitialized = false; + + /// Sets the logger to receive native logs and initializes the channel listener. + /// + /// This should be called once during SDK initialization. If [logger] is null, + /// native logging will not be initialized on the native side. + static void pipeNativeLogs(DescopeLogger? logger) { + _logger = logger; + _initChannelIfNeeded(); + + // Send logger configuration to native if a logger is set + if (logger != null) { + final levelString = switch (logger.level) { + DescopeLogger.error => 'error', + DescopeLogger.info => 'info', + _ => 'debug', + }; + _logChannel.invokeMethod('configure', { + 'level': levelString, + 'unsafe': logger.unsafe, + }); + } + } + + /// Ensures the channel listener is set up. + static void _initChannelIfNeeded() { + if (!_isInitialized) { + _isInitialized = true; + _logChannel.setMethodCallHandler(_handleNativeLog); + } + } + + static Future _handleNativeLog(MethodCall call) async { + if (call.method == 'log') { + final logger = _logger; + if (logger == null) return; + + final args = call.arguments as Map; + final levelString = args['level'] as String; + final message = args['message'] as String; + final values = (args['values'] as List).cast(); + + // Convert level string to DescopeLogger level constant + final int level; + switch (levelString) { + case 'error': + level = DescopeLogger.error; + break; + case 'info': + level = DescopeLogger.info; + break; + case 'debug': + default: + level = DescopeLogger.debug; + break; + } + + // Forward to the Flutter logger, which will filter based on its settings + // Timestamp is available in `timestamp` variable for future ordering if needed + logger.log( + level: level, + message: message, + values: values, + ); + } + } +} + diff --git a/lib/src/internal/others/native_log_bridge_unsupported.dart b/lib/src/internal/others/native_log_bridge_unsupported.dart new file mode 100644 index 00000000..1df5d401 --- /dev/null +++ b/lib/src/internal/others/native_log_bridge_unsupported.dart @@ -0,0 +1,16 @@ +import '/src/sdk/config.dart'; + +/// Stub implementation for NativeLogBridge on unsupported platforms. +/// +/// Native log bridging is only available on iOS and Android. On other platforms, +/// this no-op implementation is used. +class NativeLogBridge { + /// No-op on unsupported platforms. + /// + /// Native log bridging requires platform-specific MethodChannel communication + /// which is only implemented on iOS and Android. + static void pipeNativeLogs(DescopeLogger? logger) { + // No-op on unsupported platforms + } +} + diff --git a/lib/src/sdk/config.dart b/lib/src/sdk/config.dart index a5ab3acd..4a1c28db 100644 --- a/lib/src/sdk/config.dart +++ b/lib/src/sdk/config.dart @@ -47,17 +47,51 @@ class DescopeConfig { /// You can also customize how logging functions in the Descope SDK by creating a subclass /// of [DescopeLogger] and overriding the [DescopeLogger.output] method. See the /// documentation for that method for more details. +/// +/// You can set the logger to [DescopeLogger.basicLogger] to print error and info +/// log messages to the console. +/// +/// If you encounter any issues you can also use [DescopeLogger.debugLogger] to enable +/// more verbose logging. This will configure a simple logger that prints all logs to the +/// console. If the app is built in debug mode it will also output potentially sensitive +/// runtime values, such as full network request and response payloads, secrets and tokens +/// in cleartext, etc. +/// +/// In rare cases you might need to use [DescopeLogger.unsafeLogger] which skips the +/// debug mode check and always prints all log data including all sensitive runtime values. +/// Make sure you don't use [DescopeLogger.unsafeLogger] in release builds intended +/// for production. class DescopeLogger { /// The severity of a log message. static const error = 0; static const info = 1; static const debug = 2; + /// A simple logger that prints basic error and info logs to the console. + static final basicLogger = DescopeLogger(level: info, unsafe: false); + + /// A simple logger that prints all logs to the console, but does not output any + /// potentially unsafe runtime values unless the app is built in debug mode. + static final debugLogger = DescopeLogger(level: debug, unsafe: kDebugMode); + + /// A simple logger that prints all logs to the console, including potentially unsafe + /// runtime values such as secrets, personal information, network payloads, etc. + /// + /// - **Important**: Do not use unsafeLogger in release builds intended for production. + static final unsafeLogger = DescopeLogger(level: debug, unsafe: true); + /// The maximum log level that should be printed. int level; - /// Creates a new [DescopeLogger] object. Log level defaults to `debug` - DescopeLogger({this.level = debug}); + /// Whether to print unsafe runtime values. + /// + /// When set to `true`, log output will include potentially sensitive runtime values + /// such as personal information, network payloads, etc. This should not + /// be enabled in release builds intended for production. + bool unsafe; + + /// Creates a new [DescopeLogger] object. Log level defaults to `debug`, unsafe defaults to `false`. + DescopeLogger({this.level = debug, this.unsafe = false}); /// Formats the log message and prints it. /// @@ -65,14 +99,14 @@ class DescopeLogger { /// The [message] parameter is guaranteed to be a constant compile-time string, so /// you can assume it doesn't contain private user data or secrets and that it can /// be sent to whatever logging target or service you use. - /// The [debug] array has runtime values that might be useful when debugging + /// The [values] array has runtime values that might be useful when debugging /// issues with the Descope SDK. Since it might contain sensitive information - /// its contents are only provided in `debug` builds. In `release` builds it + /// its contents are only provided when [unsafe] is set to `true`. Otherwise it /// is always an empty array. - void output({required int level, required String message, required List debug}) { + void output({required int level, required String message, required List values}) { var text = "[${DescopeSdk.name}] $message"; - if (debug.isNotEmpty) { - text += " (${debug.map((v) => v.toString()).join(", ")})"; + if (values.isNotEmpty) { + text += " (${values.map((v) => v.toString()).join(", ")})"; } // ignore: avoid_print print(text); @@ -81,7 +115,7 @@ class DescopeLogger { /// Called by other code in the Descope SDK to output log messages. void log({required int level, required String message, List values = const []}) { if (level <= this.level) { - output(level: level, message: message, debug: kDebugMode ? values : const []); + output(level: level, message: message, values: unsafe ? values : const []); } } } diff --git a/lib/src/sdk/sdk.dart b/lib/src/sdk/sdk.dart index 5ae9a691..6399b420 100644 --- a/lib/src/sdk/sdk.dart +++ b/lib/src/sdk/sdk.dart @@ -1,5 +1,6 @@ // ignore_for_file: deprecated import '/src/internal/http/descope_client.dart'; +import '/src/internal/others/native_log_bridge.dart'; import '/src/internal/routes/auth.dart'; import '/src/internal/routes/enchanted_link.dart'; import '/src/internal/routes/flow.dart'; @@ -68,6 +69,8 @@ class DescopeSdk { // init config final config = DescopeConfig(projectId: projectId); configure?.call(config); + // init native log bridge to receive logs from native SDK layers + NativeLogBridge.pipeNativeLogs(config.logger); // init auth methods final client = DescopeClient(config); return DescopeSdk._internal(config, Flow(client), Auth(client), Otp(client), Totp(client), MagicLink(client), EnchantedLink(client), OAuth(client), Sso(client), Passkey(client), Password(client)); From d594f3695db08039a3637cb7baa1aabce723b84d Mon Sep 17 00:00:00 2001 From: Itai Hanski Date: Thu, 15 Jan 2026 12:37:10 +0200 Subject: [PATCH 3/7] Bump version to 0.9.12 --- CHANGELOG.md | 5 +++++ README.md | 8 ++++---- lib/src/sdk/sdk.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9df38fbd..f368d1cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.9.12 + +- Stream native (iOS/Android) logs to the Flutter `DescopeLogger` +- **Breaking Change**: Renamed `DescopeLogger` properties to `level` and `unsafe` + # 0.9.11 - Support links in iOS native flows - Support `mailto:` links everywhere diff --git a/README.md b/README.md index e7c521fc..e9b439ba 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,10 @@ Descope.setup(''); Descope.setup('', (config) { // set a custom base URL (needs to be set up in the Descope console) config.baseUrl = 'https://my.app.com'; - // enable the logger - if (kDebugMode) { - config.logger = DescopeLogger(); - } + // Enable the logger for debugging. + // You can use DescopeLogger.debugLogger (or DescopeLogger.unsafeLogger) when testing out the SDK. + // For production it is advised to provide a custom implementation hooked up to the application's log monitoring system. + config.logger = DescopeLogger.debugLogger; }); // Load any available sessions diff --git a/lib/src/sdk/sdk.dart b/lib/src/sdk/sdk.dart index 6399b420..d452d897 100644 --- a/lib/src/sdk/sdk.dart +++ b/lib/src/sdk/sdk.dart @@ -23,7 +23,7 @@ class DescopeSdk { static const name = 'DescopeFlutter'; /// The Descope SDK version - static const version = '0.9.11'; + static const version = '0.9.12'; /// The configuration of the [DescopeSdk] instance. final DescopeConfig config; diff --git a/pubspec.yaml b/pubspec.yaml index 539a102b..631cb3d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: descope description: A Flutter package for working with the Descope API. -version: 0.9.11 +version: 0.9.12 homepage: https://www.descope.com repository: https://github.com/descope/descope-flutter issue_tracker: https://github.com/descope/descope-flutter/issues From fde6be4df47d18999d5af4ca8519b5aa3f40eefb Mon Sep 17 00:00:00 2001 From: Itai Hanski Date: Thu, 15 Jan 2026 13:03:43 +0200 Subject: [PATCH 4/7] Update README.md Co-authored-by: Gil Shapira --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9b439ba..82a6aaca 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Descope.setup('', (config) { // set a custom base URL (needs to be set up in the Descope console) config.baseUrl = 'https://my.app.com'; // Enable the logger for debugging. - // You can use DescopeLogger.debugLogger (or DescopeLogger.unsafeLogger) when testing out the SDK. + // You can use DescopeLogger.debugLogger (or DescopeLogger.unsafeLogger) during development or to diagnose issues. // For production it is advised to provide a custom implementation hooked up to the application's log monitoring system. config.logger = DescopeLogger.debugLogger; }); From 61228da4844f7bf443f0de128fb54a7da44b29cd Mon Sep 17 00:00:00 2001 From: Itai Hanski Date: Thu, 15 Jan 2026 13:04:09 +0200 Subject: [PATCH 5/7] Update lib/src/internal/others/native_log_bridge_native.dart Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/src/internal/others/native_log_bridge_native.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/internal/others/native_log_bridge_native.dart b/lib/src/internal/others/native_log_bridge_native.dart index 7ad17124..ae333729 100644 --- a/lib/src/internal/others/native_log_bridge_native.dart +++ b/lib/src/internal/others/native_log_bridge_native.dart @@ -68,7 +68,6 @@ class NativeLogBridge { } // Forward to the Flutter logger, which will filter based on its settings - // Timestamp is available in `timestamp` variable for future ordering if needed logger.log( level: level, message: message, From 4318f496134655605b5484d34526950912df2dca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:05:28 +0000 Subject: [PATCH 6/7] Initial plan From f4e1497bf3a6d671769d799907d0fbd18f0a40cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:07:14 +0000 Subject: [PATCH 7/7] docs: fix grammar in Flow.swift comment Co-authored-by: itaihanski <1485548+itaihanski@users.noreply.github.com> --- ios/Classes/descope-swift-sdk/flows/Flow.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Classes/descope-swift-sdk/flows/Flow.swift b/ios/Classes/descope-swift-sdk/flows/Flow.swift index dcc942ab..b328ce41 100644 --- a/ios/Classes/descope-swift-sdk/flows/Flow.swift +++ b/ios/Classes/descope-swift-sdk/flows/Flow.swift @@ -171,7 +171,7 @@ extension DescopeFlow: CustomStringConvertible { } } -/// Convenience constructor when use Descope's Flow hosting service +/// Convenience constructor when using Descope's Flow hosting service extension DescopeFlow { /// Creates a new ``DescopeFlow`` object that encapsulates a single flow run. ///