diff --git a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/Auth.kt b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/Auth.kt index 44ba07388..41c3a4b12 100644 --- a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/Auth.kt +++ b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/Auth.kt @@ -23,6 +23,7 @@ import io.github.jan.supabase.plugins.MainPlugin import io.github.jan.supabase.plugins.SupabasePluginProvider import io.ktor.client.plugins.HttpRequestTimeoutException import kotlinx.coroutines.flow.StateFlow +import kotlinx.serialization.json.JsonObject /** * Plugin to interact with the Supabase Auth API @@ -127,6 +128,17 @@ sealed interface Auth : MainPlugin, CustomSerializationPlugin { config: (C.() -> Unit)? = null ) + /** + * Signs in the user without any credentials. This will create a new user session with a new access token. + * + * If you want to upgrade this anonymous user to a real user, use [linkIdentity] to link an OAuth identity or [modifyUser] to add an email or phone. + * + * @param data Extra data for the user + * @param captchaToken The captcha token to use + */ + @SupabaseExperimental + suspend fun signInAnonymously(data: JsonObject? = null, captchaToken: String? = null) + /** * Links an OAuth Identity to an existing user. * diff --git a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthExtensions.kt b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthExtensions.kt index 63812881e..cbfb6411c 100644 --- a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthExtensions.kt +++ b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthExtensions.kt @@ -1,7 +1,9 @@ package io.github.jan.supabase.gotrue +import io.github.jan.supabase.encodeToJsonElement import io.github.jan.supabase.gotrue.user.UserSession import io.github.jan.supabase.logging.d +import kotlinx.serialization.json.jsonObject internal fun noDeeplinkError(arg: String): Nothing = error(""" Trying to use a deeplink as a redirect url, but no deeplink $arg is set in the GoTrueConfig. @@ -34,6 +36,7 @@ fun Auth.parseSessionFromFragment(fragment: String): UserSession { val type = sessionParts["type"] ?: "" val providerToken = sessionParts["provider_token"] val providerRefreshToken = sessionParts["provider_refresh_token"] + return UserSession( accessToken = accessToken, refreshToken = refreshToken, @@ -51,4 +54,14 @@ fun Auth.parseSessionFromFragment(fragment: String): UserSession { * @param url The url to parse the session from * @return The parsed session. Note that the user will be null, but you can retrieve it using [Auth.retrieveUser] */ -fun Auth.parseSessionFromUrl(url: String): UserSession = parseSessionFromFragment(url.substringAfter("#")) \ No newline at end of file +fun Auth.parseSessionFromUrl(url: String): UserSession = parseSessionFromFragment(url.substringAfter("#")) + +/** + * Signs in the user without any credentials. This will create a new user session with a new access token. + * + * If you want to upgrade this anonymous user to a real user, use [Auth.linkIdentity] to link an OAuth identity or [Auth.modifyUser] to add an email or phone. + * + * @param data Extra data for the user + * @param captchaToken The captcha token to use + */ +suspend inline fun Auth.signInAnonymously(data: T, captchaToken: String? = null) = signInAnonymously(serializer.encodeToJsonElement(data).jsonObject, captchaToken) \ No newline at end of file diff --git a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthImpl.kt b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthImpl.kt index 68be2b983..8ed060488 100644 --- a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthImpl.kt +++ b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/AuthImpl.kt @@ -43,6 +43,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.datetime.Clock +import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObjectBuilder import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.encodeToJsonElement @@ -111,6 +112,19 @@ internal class AuthImpl( importSession(it, source = SessionSource.SignIn(provider)) }, redirectUrl, config) + override suspend fun signInAnonymously(data: JsonObject?, captchaToken: String?) { + val response = api.postJson("signup", buildJsonObject { + data?.let { put("data", it) } + captchaToken?.let { + putJsonObject("gotrue_meta_security") { + put("captcha_token", captchaToken) + } + } + }) + val session = response.safeBody() + importSession(session, source = SessionSource.AnonymousSignIn) + } + override suspend fun > signUpWith( provider: Provider, redirectUrl: String?, diff --git a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/SessionStatus.kt b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/SessionStatus.kt index bb966ca2d..d7bbf1bd5 100644 --- a/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/SessionStatus.kt +++ b/GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/SessionStatus.kt @@ -51,6 +51,11 @@ sealed interface SessionSource { */ data object Storage : SessionSource + /** + * The session was loaded from an anonymous sign in + */ + data object AnonymousSignIn : SessionSource + /** * The session was loaded from a sign in * @param provider The provider that was used to sign in