Skip to content

Commit 4c25a3e

Browse files
authored
feat(auth): Add signInAnonymously (#297)
* feat(auth): add `signInAnonymously` method * Add tests
1 parent bfbcddd commit 4c25a3e

File tree

8 files changed

+135
-5
lines changed

8 files changed

+135
-5
lines changed

Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
79BD76772B59C3E300CA3D68 /* UserStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD76762B59C3E300CA3D68 /* UserStore.swift */; };
4848
79BD76792B59C53900CA3D68 /* ChannelStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD76782B59C53900CA3D68 /* ChannelStore.swift */; };
4949
79BD767B2B59C61300CA3D68 /* MessageStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79BD767A2B59C61300CA3D68 /* MessageStore.swift */; };
50+
79C9B8E52BBB16C0003AD942 /* SignInAnonymously.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79C9B8E42BBB16C0003AD942 /* SignInAnonymously.swift */; };
5051
79D884CA2B3C18830009EA4A /* SlackCloneApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79D884C92B3C18830009EA4A /* SlackCloneApp.swift */; };
5152
79D884CC2B3C18830009EA4A /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79D884CB2B3C18830009EA4A /* AppView.swift */; };
5253
79D884CE2B3C18840009EA4A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 79D884CD2B3C18840009EA4A /* Assets.xcassets */; };
@@ -112,6 +113,7 @@
112113
79BD76762B59C3E300CA3D68 /* UserStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserStore.swift; sourceTree = "<group>"; };
113114
79BD76782B59C53900CA3D68 /* ChannelStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelStore.swift; sourceTree = "<group>"; };
114115
79BD767A2B59C61300CA3D68 /* MessageStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStore.swift; sourceTree = "<group>"; };
116+
79C9B8E42BBB16C0003AD942 /* SignInAnonymously.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInAnonymously.swift; sourceTree = "<group>"; };
115117
79D884C72B3C18830009EA4A /* SlackClone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SlackClone.app; sourceTree = BUILT_PRODUCTS_DIR; };
116118
79D884C92B3C18830009EA4A /* SlackCloneApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SlackCloneApp.swift; sourceTree = "<group>"; };
117119
79D884CB2B3C18830009EA4A /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
@@ -258,6 +260,7 @@
258260
793E030C2B2DAB5700AC7DED /* SignInWithApple.swift */,
259261
7940E3142B36187A0089BEE1 /* GoogleSignInWithWebFlow.swift */,
260262
79E2B5542B9788BF0042CD21 /* GoogleSignInSDKFlow.swift */,
263+
79C9B8E42BBB16C0003AD942 /* SignInAnonymously.swift */,
261264
);
262265
path = Auth;
263266
sourceTree = "<group>";
@@ -505,6 +508,7 @@
505508
793895CA2954ABFF0044F2B8 /* ExamplesApp.swift in Sources */,
506509
797EFB682BABD90500098D6B /* Stringfy.swift in Sources */,
507510
797EFB6C2BABE1B800098D6B /* FileObjectDetailView.swift in Sources */,
511+
79C9B8E52BBB16C0003AD942 /* SignInAnonymously.swift in Sources */,
508512
797EFB6A2BABDF3800098D6B /* BucketDetailView.swift in Sources */,
509513
793E030D2B2DAB5700AC7DED /* SignInWithApple.swift in Sources */,
510514
793E030B2B2CEDDA00AC7DED /* ActionState.swift in Sources */,

Examples/Examples/Auth/AuthView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct AuthView: View {
1414
case signInWithApple
1515
case googleSignInWebFlow
1616
case googleSignInSDKFlow
17+
case signInAnonymously
1718

1819
var title: String {
1920
switch self {
@@ -22,6 +23,7 @@ struct AuthView: View {
2223
case .signInWithApple: "Sign in with Apple"
2324
case .googleSignInWebFlow: "Google Sign in (Web Flow)"
2425
case .googleSignInSDKFlow: "Google Sign in (GIDSignIn SDK Flow)"
26+
case .signInAnonymously: "Sign in Anonymously"
2527
}
2628
}
2729
}
@@ -50,6 +52,7 @@ extension AuthView.Option: View {
5052
case .signInWithApple: SignInWithApple()
5153
case .googleSignInWebFlow: GoogleSignInWithWebFlow()
5254
case .googleSignInSDKFlow: GoogleSignInSDKFlow()
55+
case .signInAnonymously: SignInAnonymously()
5356
}
5457
}
5558
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// SignInAnonymously.swift
3+
// Examples
4+
//
5+
// Created by Guilherme Souza on 01/04/24.
6+
//
7+
8+
import Supabase
9+
import SwiftUI
10+
11+
struct SignInAnonymously: View {
12+
var body: some View {
13+
Button("Sign in") {
14+
Task {
15+
do {
16+
try await supabase.auth.signInAnonymously()
17+
} catch {
18+
debug("Error signin in anonymously: \(error)")
19+
}
20+
}
21+
}
22+
}
23+
}
24+
25+
#Preview {
26+
SignInAnonymously()
27+
}

Examples/supabase/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,6 @@ redirect_uri = ""
7777
url = ""
7878

7979
[auth.external.github]
80-
enabled = true
80+
enabled = false
8181
client_id = "12d1131cd3582f942c71"
8282
secret = "env(SUPABASE_AUTH_EXTERNAL_GITHUB_SECRET)"

Sources/Auth/AuthClient.swift

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,31 @@ public actor AuthClient {
362362
)
363363
}
364364

365+
/// Creates a new anonymous user.
366+
/// - Parameters:
367+
/// - data: A custom data object to store the user's metadata. This maps to the
368+
/// `auth.users.raw_user_meta_data` column. The `data` should be a JSON object that includes
369+
/// user-specific info, such as their first and last name.
370+
/// - captchaToken: Verification token received when the user completes the captcha.
371+
@discardableResult
372+
public func signInAnonymously(
373+
data: [String: AnyJSON]? = nil,
374+
captchaToken: String? = nil
375+
) async throws -> Session {
376+
try await _signIn(
377+
request: Request(
378+
path: "/signup",
379+
method: .post,
380+
body: configuration.encoder.encode(
381+
SignUpRequest(
382+
data: data,
383+
gotrueMetaSecurity: captchaToken.map { AuthMetaSecurity(captchaToken: $0) }
384+
)
385+
)
386+
)
387+
)
388+
}
389+
365390
private func _signIn(request: Request) async throws -> Session {
366391
await sessionManager.remove()
367392

@@ -370,10 +395,8 @@ public actor AuthClient {
370395
decoder: configuration.decoder
371396
)
372397

373-
if session.user.emailConfirmedAt != nil || session.user.confirmedAt != nil {
374-
try await sessionManager.update(session)
375-
eventEmitter.emit(.signedIn, session: session)
376-
}
398+
try await sessionManager.update(session)
399+
eventEmitter.emit(.signedIn, session: session)
377400

378401
return session
379402
}

Tests/AuthTests/AuthClientTests.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,61 @@ final class AuthClientTests: XCTestCase {
195195
XCTAssertEqual(removeCallCount.value, 1)
196196
}
197197

198+
func testSignInAnonymously() async throws {
199+
let emitReceivedEvents = LockIsolated<[(AuthChangeEvent, Session?)]>([])
200+
201+
eventEmitter.emit = { @Sendable event, session, _ in
202+
emitReceivedEvents.withValue {
203+
$0.append((event, session))
204+
}
205+
}
206+
sessionManager.remove = { @Sendable in }
207+
sessionManager.update = { @Sendable _ in }
208+
209+
api.execute = { @Sendable _ in
210+
.stub(
211+
"""
212+
{
213+
"access_token" : "eyJhbGciOiJIUzI1NiIsImtpZCI6ImpIaU1GZmtNTzRGdVROdXUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzExOTk0NzEzLCJpYXQiOjE3MTE5OTExMTMsImlzcyI6Imh0dHBzOi8vYWp5YWdzaHV6bnV2anFoampmdG8uc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJiZmE5MjU0LWM1ZDEtNGNmZi1iYTc2LTU2YmYwM2IwNWEwMSIsImVtYWlsIjoiIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnt9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJhbm9ueW1vdXMiLCJ0aW1lc3RhbXAiOjE3MTE5OTExMTN9XSwic2Vzc2lvbl9pZCI6ImMyODlmYTcwLWIzYWUtNDI1Yi05MDQxLWUyZjVhNzBlZTcyYSIsImlzX2Fub255bW91cyI6dHJ1ZX0.whBzmyMv3-AQSaiY6Fi-v_G68Q8oULhB7axImj9qOdw",
214+
"expires_at" : 1711994713,
215+
"expires_in" : 3600,
216+
"refresh_token" : "0xS9iJUWdXnWlCJtFiXk5A",
217+
"token_type" : "bearer",
218+
"user" : {
219+
"app_metadata" : {
220+
221+
},
222+
"aud" : "authenticated",
223+
"created_at" : "2024-04-01T17:05:13.013312Z",
224+
"email" : "",
225+
"id" : "bbfa9254-c5d1-4cff-ba76-56bf03b05a01",
226+
"identities" : [
227+
228+
],
229+
"is_anonymous" : true,
230+
"last_sign_in_at" : "2024-04-01T17:05:13.018294975Z",
231+
"phone" : "",
232+
"role" : "authenticated",
233+
"updated_at" : "2024-04-01T17:05:13.022041Z",
234+
"user_metadata" : {
235+
236+
}
237+
}
238+
}
239+
""",
240+
code: 200
241+
)
242+
}
243+
244+
let sut = makeSUT()
245+
246+
try await sut.signInAnonymously()
247+
248+
let events = emitReceivedEvents.value.map(\.0)
249+
250+
XCTAssertEqual(events, [.signedIn])
251+
}
252+
198253
private func makeSUT() -> AuthClient {
199254
let configuration = AuthClient.Configuration(
200255
url: clientURL,

Tests/AuthTests/RequestsTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,17 @@ final class RequestsTests: XCTestCase {
399399
}
400400
}
401401

402+
func testSignInAnonymously() async {
403+
let sut = makeSUT()
404+
405+
await assert {
406+
try await sut.signInAnonymously(
407+
data: ["custom_key": .string("custom_value")],
408+
captchaToken: "captcha-token"
409+
)
410+
}
411+
}
412+
402413
private func assert(_ block: () async throws -> Void) async {
403414
do {
404415
try await block()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
curl \
2+
--request POST \
3+
--header "Apikey: dummy.api.key" \
4+
--header "Content-Type: application/json" \
5+
--header "X-Client-Info: gotrue-swift/x.y.z" \
6+
--data "{\"data\":{\"custom_key\":\"custom_value\"},\"gotrue_meta_security\":{\"captcha_token\":\"captcha-token\"}}" \
7+
"http://localhost:54321/auth/v1/signup"

0 commit comments

Comments
 (0)