Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class FirebaseAppCheckPlugin : FlutterFirebasePlugin, FlutterPlugin, FirebaseApp
androidProvider: String?,
appleProvider: String?,
debugToken: String?,
appleProviderSiteKey: String?,
callback: (Result<Unit>) -> Unit
) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ interface FirebaseAppCheckHostApi {
androidProvider: String?,
appleProvider: String?,
debugToken: String?,
appleProviderSiteKey: String?,
callback: (Result<Unit>) -> Unit
)

Expand Down Expand Up @@ -306,15 +307,20 @@ interface FirebaseAppCheckHostApi {
val androidProviderArg = args[1] as String?
val appleProviderArg = args[2] as String?
val debugTokenArg = args[3] as String?
api.activate(appNameArg, androidProviderArg, appleProviderArg, debugTokenArg) {
result: Result<Unit> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(GeneratedAndroidFirebaseAppCheckPigeonUtils.wrapError(error))
} else {
reply.reply(GeneratedAndroidFirebaseAppCheckPigeonUtils.wrapResult(null))
}
}
val appleProviderSiteKeyArg = args[4] as String?
api.activate(
appNameArg,
androidProviderArg,
appleProviderArg,
debugTokenArg,
appleProviderSiteKeyArg) { result: Result<Unit> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(GeneratedAndroidFirebaseAppCheckPigeonUtils.wrapError(error))
} else {
reply.reply(GeneratedAndroidFirebaseAppCheckPigeonUtils.wrapResult(null))
}
}
}
} else {
channel.setMessageHandler(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ final class PigeonError: Error {
}

var localizedDescription: String {
"PigeonError(code: \(code), message: \(message ?? "<nil>"), details: \(details ?? "<nil>")"
return
"PigeonError(code: \(code), message: \(message ?? "<nil>"), details: \(details ?? "<nil>")"
}
}

private func wrapResult(_ result: Any?) -> [Any?] {
[result]
return [result]
}

private func wrapError(_ error: Any) -> [Any?] {
Expand All @@ -58,7 +59,7 @@ private func wrapError(_ error: Any) -> [Any?] {
}

private func isNullish(_ value: Any?) -> Bool {
value is NSNull || value == nil
return value is NSNull || value == nil
}

private func nilOrValue<T>(_ value: Any?) -> T? {
Expand All @@ -67,7 +68,7 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
}

private func doubleEqualsFirebaseAppCheckMessages(_ lhs: Double, _ rhs: Double) -> Bool {
(lhs.isNaN && rhs.isNaN) || lhs == rhs
return (lhs.isNaN && rhs.isNaN) || lhs == rhs
}

private func doubleHashFirebaseAppCheckMessages(_ value: Double, _ hasher: inout Hasher) {
Expand Down Expand Up @@ -144,7 +145,7 @@ func deepEqualsFirebaseAppCheckMessages(_ lhs: Any?, _ rhs: Any?) -> Bool {

func deepHashFirebaseAppCheckMessages(value: Any?, hasher: inout Hasher) {
let cleanValue = nilOrValue(value) as Any?
if let cleanValue {
if let cleanValue = cleanValue {
if let doubleValue = cleanValue as? Double {
doubleHashFirebaseAppCheckMessages(doubleValue, &hasher)
} else if let valueList = cleanValue as? [Any?] {
Expand Down Expand Up @@ -178,7 +179,7 @@ func deepHashFirebaseAppCheckMessages(value: Any?, hasher: inout Hasher) {
/// Generated class from Pigeon that represents data sent in messages.
struct InternalAppCheckTokenResult: Hashable {
var token: String
var expirationTimestamp: Int64?
var expirationTimestamp: Int64? = nil

// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> InternalAppCheckTokenResult? {
Expand All @@ -190,23 +191,18 @@ struct InternalAppCheckTokenResult: Hashable {
expirationTimestamp: expirationTimestamp
)
}

func toList() -> [Any?] {
[
return [
token,
expirationTimestamp,
]
}

static func == (lhs: InternalAppCheckTokenResult, rhs: InternalAppCheckTokenResult) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return deepEqualsFirebaseAppCheckMessages(lhs.token, rhs.token)
&& deepEqualsFirebaseAppCheckMessages(
lhs.expirationTimestamp,
rhs.expirationTimestamp
)
&& deepEqualsFirebaseAppCheckMessages(lhs.expirationTimestamp, rhs.expirationTimestamp)
}

func hash(into hasher: inout Hasher) {
Expand All @@ -220,7 +216,7 @@ private class FirebaseAppCheckMessagesPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 129:
return InternalAppCheckTokenResult.fromList(readValue() as! [Any?])
return InternalAppCheckTokenResult.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
Expand All @@ -240,29 +236,26 @@ private class FirebaseAppCheckMessagesPigeonCodecWriter: FlutterStandardWriter {

private class FirebaseAppCheckMessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter {
override func reader(with data: Data) -> FlutterStandardReader {
FirebaseAppCheckMessagesPigeonCodecReader(data: data)
return FirebaseAppCheckMessagesPigeonCodecReader(data: data)
}

override func writer(with data: NSMutableData) -> FlutterStandardWriter {
FirebaseAppCheckMessagesPigeonCodecWriter(data: data)
return FirebaseAppCheckMessagesPigeonCodecWriter(data: data)
}
}

class FirebaseAppCheckMessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
static let shared =
FirebaseAppCheckMessagesPigeonCodec(
readerWriter: FirebaseAppCheckMessagesPigeonCodecReaderWriter()
)
static let shared = FirebaseAppCheckMessagesPigeonCodec(
readerWriter: FirebaseAppCheckMessagesPigeonCodecReaderWriter())
}

/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol FirebaseAppCheckHostApi {
func activate(
appName: String, androidProvider: String?, appleProvider: String?,
debugToken: String?, completion: @escaping (Result<Void, Error>) -> Void)
appName: String, androidProvider: String?, appleProvider: String?, debugToken: String?,
appleProviderSiteKey: String?, completion: @escaping (Result<Void, Error>) -> Void)
func getToken(
appName: String, forceRefresh: Bool,
completion: @escaping (Result<String?, Error>) -> Void)
appName: String, forceRefresh: Bool, completion: @escaping (Result<String?, Error>) -> Void)
func getTokenResult(
appName: String, forceRefresh: Bool,
completion: @escaping (Result<InternalAppCheckTokenResult?, Error>) -> Void)
Expand All @@ -271,18 +264,13 @@ protocol FirebaseAppCheckHostApi {
completion: @escaping (Result<Void, Error>) -> Void)
func registerTokenListener(appName: String, completion: @escaping (Result<String, Error>) -> Void)
func getLimitedUseAppCheckToken(
appName: String,
completion: @escaping (Result<String, Error>) -> Void)
appName: String, completion: @escaping (Result<String, Error>) -> Void)
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class FirebaseAppCheckHostApiSetup {
static var codec: FlutterStandardMessageCodec {
FirebaseAppCheckMessagesPigeonCodec.shared
}

/// Sets up an instance of `FirebaseAppCheckHostApi` to handle messages through the
/// `binaryMessenger`.
static var codec: FlutterStandardMessageCodec { FirebaseAppCheckMessagesPigeonCodec.shared }
/// Sets up an instance of `FirebaseAppCheckHostApi` to handle messages through the `binaryMessenger`.
static func setUp(
binaryMessenger: FlutterBinaryMessenger, api: FirebaseAppCheckHostApi?,
messageChannelSuffix: String = ""
Expand All @@ -291,21 +279,18 @@ class FirebaseAppCheckHostApiSetup {
let activateChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.activate\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
activateChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
let androidProviderArg: String? = nilOrValue(args[1])
let appleProviderArg: String? = nilOrValue(args[2])
let debugTokenArg: String? = nilOrValue(args[3])
let appleProviderSiteKeyArg: String? = nilOrValue(args[4])
api.activate(
appName: appNameArg,
androidProvider: androidProviderArg,
appleProvider: appleProviderArg,
debugToken: debugTokenArg
appName: appNameArg, androidProvider: androidProviderArg, appleProvider: appleProviderArg,
debugToken: debugTokenArg, appleProviderSiteKey: appleProviderSiteKeyArg
) { result in
switch result {
case .success:
Expand All @@ -321,10 +306,8 @@ class FirebaseAppCheckHostApiSetup {
let getTokenChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getToken\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getTokenChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
Expand All @@ -344,10 +327,8 @@ class FirebaseAppCheckHostApiSetup {
let getTokenResultChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getTokenResult\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getTokenResultChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
Expand All @@ -367,17 +348,14 @@ class FirebaseAppCheckHostApiSetup {
let setTokenAutoRefreshEnabledChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.setTokenAutoRefreshEnabled\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
setTokenAutoRefreshEnabledChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
let isTokenAutoRefreshEnabledArg = args[1] as! Bool
api.setTokenAutoRefreshEnabled(
appName: appNameArg,
isTokenAutoRefreshEnabled: isTokenAutoRefreshEnabledArg
appName: appNameArg, isTokenAutoRefreshEnabled: isTokenAutoRefreshEnabledArg
) { result in
switch result {
case .success:
Expand All @@ -393,10 +371,8 @@ class FirebaseAppCheckHostApiSetup {
let registerTokenListenerChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.registerTokenListener\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
registerTokenListenerChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
Expand All @@ -415,10 +391,8 @@ class FirebaseAppCheckHostApiSetup {
let getLimitedUseAppCheckTokenChannel = FlutterBasicMessageChannel(
name:
"dev.flutter.pigeon.firebase_app_check_platform_interface.FirebaseAppCheckHostApi.getLimitedUseAppCheckToken\(channelSuffix)",
binaryMessenger: binaryMessenger,
codec: codec
)
if let api {
binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getLimitedUseAppCheckTokenChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let appNameArg = args[0] as! String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class FirebaseAppCheckPlugin: NSObject, FlutterPlugin,

func activate(
appName: String, androidProvider: String?, appleProvider: String?,
debugToken: String?,
debugToken: String?, appleProviderSiteKey: String?,
completion: @escaping (Result<Void, Error>) -> Void
) {
guard let app = FLTFirebasePlugin.firebaseAppNamed(appName) else {
Expand All @@ -79,10 +79,24 @@ public class FirebaseAppCheckPlugin: NSObject, FlutterPlugin,
}
let provider = appleProvider ?? "deviceCheck"

if provider == "recaptcha", appleProviderSiteKey?.isEmpty ?? true {
completion(
.failure(
FlutterError(
code: "invalid-argument",
message: "A siteKey must be provided when using AppleReCaptchaProvider.",
details: nil
)
)
)
return
}

providerFactory?.configure(
app: app,
providerName: provider,
debugToken: debugToken
debugToken: debugToken,
siteKey: appleProviderSiteKey
)

completion(.success(()))
Expand Down Expand Up @@ -319,7 +333,8 @@ class FlutterAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
wrapper.configure(
app: app,
providerName: "deviceCheck",
debugToken: nil
debugToken: nil,
siteKey: nil
)
providers[app.name] = wrapper
}
Expand All @@ -329,15 +344,17 @@ class FlutterAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
func configure(
app: FirebaseApp,
providerName: String,
debugToken: String?
debugToken: String?,
siteKey: String?
) {
if providers[app.name] == nil {
providers[app.name] = AppCheckProviderWrapper()
}
providers[app.name]?.configure(
app: app,
providerName: providerName,
debugToken: debugToken
debugToken: debugToken,
siteKey: siteKey
)
}
}
Expand All @@ -348,7 +365,8 @@ class AppCheckProviderWrapper: NSObject, AppCheckProvider {
func configure(
app: FirebaseApp,
providerName: String,
debugToken: String?
debugToken: String?,
siteKey: String?
) {
switch providerName {
case "debug":
Expand All @@ -373,10 +391,12 @@ class AppCheckProviderWrapper: NSObject, AppCheckProvider {
}
case "recaptcha":
#if os(iOS)
delegateProvider = RecaptchaProvider(app: app)
if let siteKey {
delegateProvider = RecaptchaProvider(app: app, siteKey: siteKey)
}
if delegateProvider == nil {
print(
"Firebase App Check: failed to initialize RecaptchaProvider. Ensure site key is in GoogleService-Info.plist."
"Firebase App Check: failed to initialize RecaptchaProvider. Ensure a valid site key is provided."
)
}
#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class FirebaseAppCheck extends FirebasePlugin implements FirebaseService {
/// **iOS/macOS**: The default provider is "device check". Use `providerApple`
/// to configure alternative providers such as "app attest", debug providers, or
/// "app attest with fallback to device check" via `AppleAppCheckProvider`.
/// Apple reCAPTCHA requires passing a site key to `AppleReCaptchaProvider`.
/// Note: App Attest is only available on iOS 14.0+ and macOS 14.0+.
///
/// **Windows**: Only the debug provider is supported. You **must** supply a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ FirebaseAppCheckPlugin::~FirebaseAppCheckPlugin() {
void FirebaseAppCheckPlugin::Activate(
const std::string& app_name, const std::string* android_provider,
const std::string* apple_provider, const std::string* debug_token,
const std::string* apple_provider_site_key,
std::function<void(std::optional<FlutterError> reply)> result) {
// On Windows/desktop, only the Debug provider is available.
DebugAppCheckProviderFactory* factory =
Expand Down
Loading
Loading