Skip to content

Commit

Permalink
Merge branch 'development' into wasm
Browse files Browse the repository at this point in the history
# Conflicts:
#	gradle.properties
#	gradle/libs.versions.toml
  • Loading branch information
jan-tennert committed Dec 1, 2023
2 parents 59c6b59 + 84fb643 commit 4afbb44
Show file tree
Hide file tree
Showing 90 changed files with 1,350 additions and 1,041 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.github.jan.supabase.functions

import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.SupabaseSerializer
import io.github.jan.supabase.annotations.SupabaseExperimental
import io.github.jan.supabase.annotations.SupabaseInternal
import io.github.jan.supabase.encode
import io.github.jan.supabase.exceptions.BadRequestRestException
Expand Down Expand Up @@ -31,16 +30,16 @@ import io.ktor.http.HttpStatusCode
*
* To use it you need to install it to the [SupabaseClient]:
* ```kotlin
* val client = createSupabaseClient(supabaseUrl, supabaseKey) {
* val supabase = createSupabaseClient(supabaseUrl, supabaseKey) {
* install(Functions)
* }
* ```
*
* then you can use it like this:
* ```kotlin
* val response = client.functions("myFunction")
* val response = supabase.functions("myFunction")
* //or store it in a variable
* val function = client.functions.buildEdgeFunction("myFunction")
* val function = supabase.functions.buildEdgeFunction("myFunction")
* val response = function()
* ```
*/
Expand Down Expand Up @@ -126,7 +125,6 @@ class Functions(override val config: Config, override val supabaseClient: Supaba
override var jwtToken: String? = null,
) : MainConfig, CustomSerializationConfig {

@SupabaseExperimental
override var serializer: SupabaseSerializer? = null

}
Expand Down
17 changes: 9 additions & 8 deletions GoTrue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ Extends Supabase-kt with a multiplatform GoTrue client.
Supported targets:

| Target | **JVM** | **Android** | **JS** | **iOS** | **tvOS** | **watchOS** | **macOS** | **Windows** | **Linux** |
|--------|---------|-------------|--------|---------|----------|-------------|-----------|-------------|-----------|
| | | | | | ☑️ | ☑️ | | ☑️ | ☑️ |
| ------ | ------- | ----------- | ------ | ------- | -------- | ----------- | --------- | ----------- | --------- |
| ||||| ☑️ | ☑️ | | ☑️ | ☑️ |

> Native support is experimental and needs feedback
>
>
> ☑️ = No built-in OAuth support. Linux has no support for persistent session storage.
<details>
Expand Down Expand Up @@ -43,21 +43,22 @@ dependencies {
```

Install the plugin in your SupabaseClient. See the [documentation](https://supabase.com/docs/reference/kotlin/initializing) for more information

```kotlin
val client = createSupabaseClient(
val supabase = createSupabaseClient(
supabaseUrl = "https://id.supabase.co",
supabaseKey = "apikey"
) {

//...

install(Auth) {
// settings
}

}
```

# Usage

See [GoTrue documentation](https://supabase.com/docs/reference/kotlin/auth-signup) for usage
See [GoTrue documentation](https://supabase.com/docs/reference/kotlin/auth-signup) for usage
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import io.github.jan.supabase.gotrue.deepLink
import io.github.jan.supabase.gotrue.openUrl
import io.github.jan.supabase.gotrue.user.UserSession

internal actual suspend fun <Config : SSO.Config> SSO<Config>.loginWithSSO(
internal actual suspend fun SSO.loginWithSSO(
supabaseClient: SupabaseClient,
onSuccess: suspend (UserSession) -> Unit,
redirectUrl: String?,
config: (Config.() -> Unit)?
config: (SSO.Config.() -> Unit)?
) {
val gotrueConfig = supabaseClient.auth.config
val result = supabaseClient.auth.retrieveSSOUrl(this, redirectUrl ?: gotrueConfig.deepLink, config)
val result = supabaseClient.auth.retrieveSSOUrl(redirectUrl ?: gotrueConfig.deepLink) { config?.invoke(this) }
openUrl(Uri.parse(result.url), gotrueConfig.defaultExternalAuthAction)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.github.jan.supabase.gotrue

import co.touchlab.kermit.Logger
import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.annotations.SupabaseExperimental
import io.github.jan.supabase.gotrue.user.UserSession
import kotlinx.coroutines.launch
import platform.Foundation.NSURL
Expand All @@ -15,7 +14,6 @@ import platform.Foundation.NSURLQueryItem
* @param url The url from the ios app delegate
* @param onSessionSuccess The callback when the session was successfully imported
*/
@SupabaseExperimental
fun SupabaseClient.handleDeeplinks(url: NSURL, onSessionSuccess: (UserSession) -> Unit = {}) {
if (url.scheme != auth.config.scheme || url.host != auth.config.host) {
Logger.d { "Received deeplink with wrong scheme or host" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import io.github.jan.supabase.gotrue.providers.openUrl
import io.github.jan.supabase.gotrue.user.UserSession
import platform.Foundation.NSURL

internal actual suspend fun <Config : SSO.Config> SSO<Config>.loginWithSSO(
internal actual suspend fun SSO.loginWithSSO(
supabaseClient: SupabaseClient,
onSuccess: suspend (UserSession) -> Unit,
redirectUrl: String?,
config: (Config.() -> Unit)?
config: (SSO.Config.() -> Unit)?
) {
val gotrue = supabaseClient.auth
val result = supabaseClient.auth.retrieveSSOUrl(this@loginWithSSO, redirectUrl ?: gotrue.config.deepLink, config)
val auth = supabaseClient.auth
val result = supabaseClient.auth.retrieveSSOUrl(redirectUrl ?: auth.config.deepLink) { config?.invoke(this) }
val url = NSURL(string = result.url)
openUrl(url)
}
115 changes: 11 additions & 104 deletions GoTrue/src/commonMain/kotlin/io/github/jan/supabase/gotrue/Auth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.github.jan.supabase.gotrue

import co.touchlab.kermit.Logger
import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.encodeToJsonElement
import io.github.jan.supabase.exceptions.HttpRequestException
import io.github.jan.supabase.exceptions.RestException
import io.github.jan.supabase.gotrue.admin.AdminApi
Expand All @@ -11,7 +10,6 @@ import io.github.jan.supabase.gotrue.providers.AuthProvider
import io.github.jan.supabase.gotrue.providers.ExternalAuthConfigDefaults
import io.github.jan.supabase.gotrue.providers.Google
import io.github.jan.supabase.gotrue.providers.OAuthProvider
import io.github.jan.supabase.gotrue.providers.builtin.DefaultAuthProvider
import io.github.jan.supabase.gotrue.providers.builtin.Email
import io.github.jan.supabase.gotrue.providers.builtin.Phone
import io.github.jan.supabase.gotrue.providers.builtin.SSO
Expand All @@ -23,8 +21,6 @@ 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
import kotlinx.serialization.json.jsonObject

/**
* Plugin to interact with the Supabase Auth API
Expand Down Expand Up @@ -103,33 +99,6 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
config: (C.() -> Unit)? = null
): R?

/**
* Logins the user with the specified [provider]
*
* Example:
* ```kotlin
* val result = gotrue.loginWith(Email) {
* email = "[email protected]"
* password = "password"
* }
* or
* gotrue.loginWith(Google) // Opens the browser to login with google
* ```
*
* @param provider the provider to use for signing up. E.g. [Email], [Phone] or [Google]
* @param redirectUrl The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android.
* @param config The configuration to use for the sign-up.
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
*/
@Deprecated("Use signInWith instead", ReplaceWith("signInWith(provider, redirectUrl, config)"))
suspend fun <C, R, Provider : AuthProvider<C, R>> loginWith(
provider: Provider,
redirectUrl: String? = null,
config: (C.() -> Unit)? = null
) = signInWith(provider, redirectUrl, config)

/**
* Signs in the user with the specified [provider]
*
Expand All @@ -140,12 +109,12 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
* password = "password"
* }
* or
* gotrue.loginWith(Google) // Opens the browser to login with google
* gotrue.signInWith(Google) // Opens the browser to login with google
* ```
*
* @param provider the provider to use for signing up. E.g. [Email], [Phone] or [Google]
* @param provider the provider to use for signing in. E.g. [Email], [Phone] or [Google]
* @param redirectUrl The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android.
* @param config The configuration to use for the sign-up.
* @param config The configuration to use for the sign-in.
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
Expand All @@ -158,11 +127,10 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {

/**
* Retrieves the sso url for the specified [type]
* @param type The type of sso to retrieve e.g. [SSO.withDomain] or [SSO.withProvider]
* @param redirectUrl The redirect url to use
* @param config The configuration to use
*/
suspend fun <Config: SSO.Config> retrieveSSOUrl(type: SSO<Config>, redirectUrl: String? = null, config: (Config.() -> Unit)? = null): SSO.Result
suspend fun retrieveSSOUrl(redirectUrl: String? = null, config: SSO.Config.() -> Unit): SSO.Result

/**
* Modifies the current user
Expand All @@ -178,32 +146,6 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
config: UserUpdateBuilder.() -> Unit
): UserInfo

/**
* Sends a one time password to the specified [provider]
*
* Example:
* ```kotlin
* gotrue.sendOtpTo(Email) {
* email = "[email protected]"
* password = "password"
* }
* ```
*
* @param provider The provider to use. Either [Email] or [Phone]
* @param createUser Whether to create a user when a user with the given credentials doesn't exist
* @param redirectUrl The redirect url to use. If you don't specify this, the platform specific will be use, like deeplinks on android.
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
*/
suspend fun <C, R, Provider : DefaultAuthProvider<C, R>> sendOtpTo(
provider: Provider,
createUser: Boolean = false,
redirectUrl: String? = null,
data: JsonObject? = null,
config: C.() -> Unit
)

/**
* Resends an existing signup confirmation email, email change email
* @param type The email otp type
Expand Down Expand Up @@ -259,12 +201,12 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
* Verifies a phone/sms otp
* @param type The type of the verification
* @param token The otp to verify
* @param phoneNumber The phone number the token was sent to
* @param phone The phone number the token was sent to
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
*/
suspend fun verifyPhoneOtp(type: OtpType.Phone, phoneNumber: String, token: String, captchaToken: String? = null)
suspend fun verifyPhoneOtp(type: OtpType.Phone, phone: String, token: String, captchaToken: String? = null)

/**
* Retrieves the user attached to the specified [jwt]
Expand All @@ -284,14 +226,14 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
suspend fun retrieveUserForCurrentSession(updateSession: Boolean = false): UserInfo

/**
* Logs out the current user, which means [sessionStatus] will be [SessionStatus.NotAuthenticated] and the access token will be revoked
* @param scope The scope of the logout.
* Signs out the current user, which means [sessionStatus] will be [SessionStatus.NotAuthenticated] and the access token will be revoked
* @param scope The scope of the sign-out.
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
* @see LogoutScope
* @see SignOutScope
*/
suspend fun logout(scope: LogoutScope = LogoutScope.LOCAL)
suspend fun signOut(scope: SignOutScope = SignOutScope.LOCAL)

/**
* Imports a user session and starts auto-refreshing if [autoRefresh] is true
Expand All @@ -307,7 +249,7 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {
suspend fun importAuthToken(accessToken: String, refreshToken: String = "", retrieveUser: Boolean = false, autoRefresh: Boolean = if(refreshToken.isNotBlank()) config.alwaysAutoRefresh else false) = importSession(UserSession(accessToken, refreshToken, "", "", 0L, "", if(retrieveUser) tryToGetUser(accessToken) else null), autoRefresh)

/**
* Retrieves the latest session from storage and starts auto-refreshing if [autoRefresh] is true or [Auth.Config.alwaysAutoRefresh] as the default parameter
* Retrieves the latest session from storage and starts auto-refreshing if [autoRefresh] is true or [AuthConfig.alwaysAutoRefresh] as the default parameter
* @return true, if a session was found, false otherwise
*/
suspend fun loadFromStorage(autoRefresh: Boolean = config.alwaysAutoRefresh): Boolean
Expand Down Expand Up @@ -393,41 +335,6 @@ sealed interface Auth : MainPlugin<AuthConfig>, CustomSerializationPlugin {

}

/**
* Sends a one time password to the specified [provider]
*
* Example:
* ```kotlin
* gotrue.sendOtpTo(Email) {
* email = "[email protected]"
* password = "password"
* }
* ```
*
* @param provider The provider to use. Either [Email] or [Phone]
* @param createUser Whether to create a user when a user with the given credentials doesn't exist
* @param redirectUrl The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android.
* @throws RestException or one of its subclasses if receiving an error response
* @throws HttpRequestTimeoutException if the request timed out
* @throws HttpRequestException on network related issues
*/
suspend inline fun <C, R, reified D : Any, Provider : DefaultAuthProvider<C, R>> Auth.sendOtpTo(
provider: Provider,
data: D,
createUser: Boolean = false,
redirectUrl: String? = null,
noinline config: C.() -> Unit = { }
): Unit = sendOtpTo(provider, createUser, redirectUrl, this.serializer.encodeToJsonElement(data).jsonObject, config)

/**
* The Auth plugin handles everything related to supabase's authentication system
*
* **DEPRECATED** Use [auth] instead
*/
@Deprecated("Use auth instead", ReplaceWith("auth", "io.github.jan.supabase.gotrue.auth"), DeprecationLevel.WARNING)
val SupabaseClient.gotrue: GoTrue
get() = pluginManager.getPlugin(GoTrue)

/**
* The Auth plugin handles everything related to Supabase's authentication system
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.github.jan.supabase.gotrue

import io.github.jan.supabase.SupabaseClientBuilder
import io.github.jan.supabase.SupabaseSerializer
import io.github.jan.supabase.annotations.SupabaseExperimental
import io.github.jan.supabase.plugins.CustomSerializationConfig
import io.github.jan.supabase.plugins.MainConfig
import kotlinx.coroutines.CoroutineDispatcher
Expand Down Expand Up @@ -93,6 +92,5 @@ enum class FlowType {
*
* Note: OTP's via a link and sign up verification links are not supported on desktop. Replace your email template to send the token instead.
*/
@SupabaseExperimental
PKCE
}
Loading

0 comments on commit 4afbb44

Please sign in to comment.