Skip to content

Commit

Permalink
fix(auth): sign out should ignore 403s (#359)
Browse files Browse the repository at this point in the history
* fix(auth): sign out should ignore 403s

* add integration test

* fix linux build
  • Loading branch information
grdsdev committed May 6, 2024
1 parent e2431b9 commit 7c4e62b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Sources/Auth/AuthClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,8 @@ public final class AuthClient: Sendable {
)
} catch {
// ignore 404s since user might not exist anymore
// ignore 401s since an invalid or expired JWT should sign out the current session
let ignoredCodes = Set([404, 401])
// ignore 401s, and 403s since an invalid or expired JWT should sign out the current session.
let ignoredCodes = Set([404, 403, 401])

if case let AuthError.api(apiError) = error, let code = apiError.code,
!ignoredCodes.contains(code)
Expand Down
31 changes: 31 additions & 0 deletions Tests/AuthTests/AuthClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,37 @@ final class AuthClientTests: XCTestCase {
XCTAssertTrue(sessionRemoved)
}

func testSignOutShouldRemoveSessionIf403Returned() async throws {
sut = makeSUT { _ in
throw AuthError.api(AuthError.APIError(code: 403))
}

let validSession = Session.validSession
try storage.storeSession(.init(session: validSession))

let eventsTask = Task {
await sut.authStateChanges.prefix(2).collect()
}

await Task.megaYield()

do {
try await sut.signOut()
} catch AuthError.api {
} catch {
XCTFail("Unexpected error: \(error)")
}

let events = await eventsTask.value.map(\.event)
let sessions = await eventsTask.value.map(\.session)

XCTAssertNoDifference(events, [.initialSession, .signedOut])
XCTAssertNoDifference(sessions, [validSession, nil])

let sessionRemoved = try storage.getSession() == nil
XCTAssertTrue(sessionRemoved)
}

func testSignInAnonymously() async throws {
let session = Session(fromMockNamed: "anonymous-sign-in-response")

Expand Down
21 changes: 21 additions & 0 deletions Tests/IntegrationTests/AuthClientIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import CustomDump
import TestHelpers
import XCTest

#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

final class AuthClientIntegrationTests: XCTestCase {
let authClient = AuthClient(
configuration: AuthClient.Configuration(
Expand Down Expand Up @@ -189,6 +193,23 @@ final class AuthClientIntegrationTests: XCTestCase {
}
}

func testDeleteAccountAndSignOut() async throws {
let response = try await signUpIfNeededOrSignIn(email: mockEmail(), password: mockPassword())

let session = try XCTUnwrap(response.session)

var request = URLRequest(url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1/rpc/delete_user")!)
request.httpMethod = "POST"
request.setValue(DotEnv.SUPABASE_ANON_KEY, forHTTPHeaderField: "apikey")
request.setValue("Bearer \(session.accessToken)", forHTTPHeaderField: "Authorization")

_ = try await URLSession.shared.data(for: request)

try await XCTAssertAuthChangeEvents([.initialSession, .signedOut]) {
try await authClient.signOut()
}
}

@discardableResult
private func signUpIfNeededOrSignIn(
email: String,
Expand Down

1 comment on commit 7c4e62b

@JOsacky
Copy link

@JOsacky JOsacky commented on 7c4e62b May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR! This fixes the issue I was having with logouts not working: supabase/supabase#25350 (comment)

Please sign in to comment.