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 @@ -108,8 +108,12 @@ class FronteggRNModule(val reactContext: ReactApplicationContext) :
}

@ReactMethod
fun logout() {
auth.logout()
fun logout(promise: Promise) {
// Resolve only after the SDK reports the logout finished, so JS can
// await the actual end of the session (parity with the iOS bridge).
auth.logout {
promise.resolve("Success")
}
}

@ReactMethod
Expand Down
5 changes: 4 additions & 1 deletion ios/FronteggRN.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
@interface RCT_EXTERN_MODULE(FronteggRN, RCTEventEmitter)

RCT_EXTERN_METHOD(subscribe)
RCT_EXTERN_METHOD(logout)
RCT_EXTERN_METHOD(
logout: (RCTPromiseResolveBlock)resolve
rejecter: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
login: (NSString *)loginHint
resolver: (RCTPromiseResolveBlock)resolve
Expand Down
26 changes: 22 additions & 4 deletions ios/FronteggRN.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,29 @@ class FronteggRN: RCTEventEmitter {
}

@objc
func logout() -> [AnyHashable : Any]! {
DispatchQueue.main.sync {
fronteggApp.auth.logout()
func logout(_ resolve: @escaping RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock) -> Void {
DispatchQueue.main.async {
// Use the completion overload so JS can await the actual end of
// the session, and push the final state when it lands. The
// fire-and-forget call relies solely on Combine-driven events,
// which can be lost when logout coincides with app-level
// teardown — leaving the JS state authenticated forever and
// breaking the next login's state-transition detection. The SDK
// completion is success-only, so there is no reject path.
self.fronteggApp.auth.logout { _ in
// Read/write hasListeners + pendingObservingState on main —
// RCTEventEmitter mutates them on main (start/stopObserving),
// so touching them off-main would be a data race.
DispatchQueue.main.async {
if self.hasListeners {
self.sendEventToJS()
} else {
self.pendingObservingState = true
}
resolve("Success")
}
}
}
return ["status": "OK"]
}

@objc
Expand Down
2 changes: 1 addition & 1 deletion src/FronteggNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function login(loginHint?: string) {
});
}

export function logout() {
export function logout(): Promise<void> {
return FronteggRN.logout();
}

Expand Down
Loading