Skip to content

Commit

Permalink
Merge pull request supabase-community#3 from grsouza/main
Browse files Browse the repository at this point in the history
Support multiple subscriptions to auth state change
  • Loading branch information
satishbabariya authored Aug 12, 2021
2 parents fe23ef5 + 2e08bea commit 13cf28e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 33 deletions.
10 changes: 5 additions & 5 deletions Sources/GoTrue/AuthChangeEvent.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

public enum AuthChangeEvent: String {
case SIGNED_IN
case SIGNED_OUT
case USER_UPDATED
case USER_DELETED
case PASSWORD_RECOVERY
case signedIn = "SIGNED_IN"
case signedOut = "SIGNED_OUT"
case userUpdated = "USER_UPDATED"
case userDeleted = "USER_DELETED"
case passwordRecovery = "PASSWORD_RECOVERY"
}
17 changes: 0 additions & 17 deletions Sources/GoTrue/CookieOptions.swift

This file was deleted.

52 changes: 41 additions & 11 deletions Sources/GoTrue/GoTrueClient.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import Foundation

public typealias AuthStateChangeCallback = (_ event: AuthChangeEvent, _ session: Session?) -> Void

public struct Subscription {
let callback: AuthStateChangeCallback

public let unsubscribe: () -> Void
}

public class GoTrueClient {
var api: GoTrueApi
var currentSession: Session?
var autoRefreshToken: Bool
var refreshTokenTimer: Timer?

public typealias StateChangeEvent = (AuthChangeEvent) -> Void
public var onAuthStateChange: StateChangeEvent?
private var stateChangeListeners: [String: Subscription] = [:]

/// Receive a notification every time an auth event happens.
/// - Returns: A subscription object which can be used to unsubscribe itself.
public func onAuthStateChange(_ callback: @escaping (_ event: AuthChangeEvent, _ session: Session?) -> Void) -> Subscription {
let id = UUID().uuidString

let subscription = Subscription(
callback: callback,
unsubscribe: { [weak self] in
self?.stateChangeListeners[id] = nil
}
)

stateChangeListeners[id] = subscription
return subscription
}

public var user: User? {
return currentSession?.user
Expand Down Expand Up @@ -35,7 +58,7 @@ public class GoTrueClient {
case let .success(data):
if let session = data.session {
self.saveSession(session: session)
self.onAuthStateChange?(.SIGNED_IN)
self.notifyAllStateChangeListeners(.signedIn)
}
completion(.success(data))
case let .failure(error):
Expand All @@ -52,7 +75,7 @@ public class GoTrueClient {
case let .success(session):
if let session = session {
self.saveSession(session: session)
self.onAuthStateChange?(.SIGNED_IN)
self.notifyAllStateChangeListeners(.signedIn)
completion(.success(session))
} else {
completion(.failure(GoTrueError(message: "failed to get session")))
Expand Down Expand Up @@ -96,7 +119,7 @@ public class GoTrueClient {
api.updateUser(accessToken: accessToken, emailChangeToken: emailChangeToken, password: password, data: data) { [unowned self] result in
switch result {
case let .success(user):
self.onAuthStateChange?(.USER_UPDATED)
self.notifyAllStateChangeListeners(.userUpdated)
self.currentSession?.user = user
if let currentSession = self.currentSession {
self.saveSessionToStorage(currentSession)
Expand All @@ -115,22 +138,23 @@ public class GoTrueClient {
let accessToken: String = queryItems.first(where: { item in item.name == "access_token" })?.value,
let expiresIn: String = queryItems.first(where: { item in item.name == "expires_in" })?.value,
let refreshToken: String = queryItems.first(where: { item in item.name == "refresh_token" })?.value,
let tokenType: String = queryItems.first(where: { item in item.name == "token_type" })?.value,
let providerToken: String = queryItems.first(where: { item in item.name == "provider_token" })?.value
let tokenType: String = queryItems.first(where: { item in item.name == "token_type" })?.value
else {
completion(.failure(GoTrueError(message: "bad credentials")))
return
}

let providerToken = queryItems.first(where: { item in item.name == "provider_token" })?.value

api.getUser(accessToken: accessToken) { [unowned self] result in
switch result {
case let .success(user):
let session = Session(accessToken: accessToken, tokenType: tokenType, expiresIn: Int(expiresIn), refreshToken: refreshToken, providerToken: providerToken, user: user)
saveSession(session: session)
self.onAuthStateChange?(.SIGNED_IN)
self.notifyAllStateChangeListeners(.signedIn)

if let type: String = queryItems.first(where: { item in item.name == "type" })?.value, type == "recovery" {
self.onAuthStateChange?(.PASSWORD_RECOVERY)
self.notifyAllStateChangeListeners(.passwordRecovery)
}

completion(.success(session))
Expand Down Expand Up @@ -166,7 +190,7 @@ public class GoTrueClient {
switch result {
case let .success(session):
self.saveSession(session: session)
self.onAuthStateChange?(.SIGNED_IN)
self.notifyAllStateChangeListeners(.signedIn)
case let .failure(error):
print(error.localizedDescription)
}
Expand Down Expand Up @@ -196,7 +220,7 @@ public class GoTrueClient {
}

removeSession()
onAuthStateChange?(.SIGNED_OUT)
notifyAllStateChangeListeners(.signedOut)
api.signOut(accessToken: accessToken) { result in
completion(result)
}
Expand All @@ -221,4 +245,10 @@ public class GoTrueClient {
}
}
}

private func notifyAllStateChangeListeners(_ event: AuthChangeEvent) {
stateChangeListeners.values.forEach {
$0.callback(event, session)
}
}
}

0 comments on commit 13cf28e

Please sign in to comment.