From 9ec590d0fa90e84f77a7312c2b48bfd229603c70 Mon Sep 17 00:00:00 2001 From: Asutosh Ranjan Date: Wed, 2 Aug 2023 22:07:45 +0530 Subject: [PATCH 1/4] spotify OAuth --- app/views/docs/oauth-providers/spotify.md | 342 ++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 app/views/docs/oauth-providers/spotify.md diff --git a/app/views/docs/oauth-providers/spotify.md b/app/views/docs/oauth-providers/spotify.md new file mode 100644 index 000000000..b66d80b9b --- /dev/null +++ b/app/views/docs/oauth-providers/spotify.md @@ -0,0 +1,342 @@ +# Spotify provider + +Appwrite allows you to authenticate users using their Spotify account through the Spotify OAuth2 provider. OAuth authentication is a great way to reduce friction for your users and increase user conversion by simplifying the signup process. You can learn more about Appwrite's other OAuth2 providers [here](placeholder link). + +## Enabling the Spotify provider +Before you can use Spotify to authenticate users, you need to enable the provider in your Appwrite console. +1. Navigate to your Appwrite project +2. Navigate to **Auth** > **Settings** +3. Find and open the OAuth provider +4. In the **Spotify OAuth2 Settings** modal, use the toggle to enable the provider + +Don't close this modal, we'll need to create a Spotify app to complete this form. + +## Creating a Spotify app for OAuth +To use Spotify OAuth with Appwrite, you need to create a Spotify app using a Spotify developer account. You can do this by following the [Creating Spotify App](https://developer.spotify.com/documentation/web-api/concepts/apps) guide, in the [Spotify Dashboard](https://developer.spotify.com/dashboard). While creating a new Spotify app in the **Redirect URI** filed, provide the **URI** found in the **Spotify OAuth2 Settings** modal from your Appwrite console. + +After you've created your Spotify app, you can head back to your Appwrite console to complete the form in the **Spotify OAuth2 Settings** modal. +- You can find the **Client ID** in your Spotify app settings menu and provide this in the **App ID** field in the **Spotify OAuth2 Settings** modal from the Appwrite console. +- In the settings menu click on the **View client secret** button to get your apps client secret. +- Copy the client secret and provide this in the **App Secret** field in the **Spotify OAuth2 Settings** modal from the Appwrite console. + +## Authenticating +You can use any of the Appwrite Client SDKs to authenticate users with their Spotify account. + +### Web +When a user calls the [Create OAuth2 Session](https://appwrite.io/docs/client/account#accountCreateOAuth2Session) endpoint in your web app, they will be taken to Spotify's OAuth page to complete their login. + +After authenticating, they'll be redirected back to your app using either the `success` or `failure` URLs provided. To provide the best experience to your users, make sure to **implement and provide both routes** to prompt the user about successful and failed authentication attempts. + +```js +import { Client, Account } from "appwrite"; + +const client = new Client(); + +const account = new Account(client); + +client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('[PROJECT_ID]') // Your project ID +; + +// Go to Spotify OAuth login page +account.createOAuth2Session('spotify', '[LINK_ON_SUCCESS]', '[LINK_ON_FAILURE]'); +``` + +### Flutter +You can use OAuth in your Flutter application, but some platforms like Android and Apple requires additional configuration to enable the OAuth callback, so that users can be redirected back to your app. + +#### Android OAuth callback + +In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `` tag, along side the existing `` tags in your `AndroidManifest.xml`. Be sure to replace the `[PROJECT_ID]` string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console. + +```xml + + ... + + ... + + + + + + + + + + + +``` + +#### Apple + +In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`. Be sure to replace the `[PROJECT_ID]` string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console. + +```xml +CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + io.appwrite + CFBundleURLSchemes + + appwrite-callback-[PROJECT_ID] + + + +``` + +To authenticate a user in your Flutter application, use the [Create OAuth2 Session](https://appwrite.io/docs/client/account?sdk=flutter-default#accountCreateOAuth2Session) endpoint. + +```dart +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = new Client(); + final account = new Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint + .setProject('[PROJECT_ID]') // YOUR PROJECT ID + ; + + // OAuth Login, for simplest implementation you can leave both success and + // failure link empty so that Appwrite handles everything. + await account.createOAuth2Session(provider: 'spotify'); + +} +``` + +### Android (Kotlin) +Before you can add OAuth to your Android app, you need to setup a callback for your OAuth flow. + +In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `` tag, along side the existing `` tags in your `AndroidManifest.xml`. Be sure to replace the `[PROJECT_ID]` string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console. + +```xml + + ... + + ... + + + + + + + + + + + +``` + +To authenticate a user in your Android application, use the [Create OAuth2 Session](https://appwrite.io/docs/client/account?sdk=android-kotlin#accountCreateOAuth2Session) endpoint. + +```kotlin +import io.appwrite.Client +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]") // Your project ID + +val account = Account(client) + +account.createOAuth2Session(provider = "spotify") +``` + +### Android (Java) +Before you can add OAuth to your Android app, you need to setup a callback for your OAuth flow. + +In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `` tag, along side the existing `` tags in your `AndroidManifest.xml`. Be sure to replace the `[PROJECT_ID]` string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console. + +```xml + + ... + + ... + + + + + + + + + + + +``` + +To authenticate a user in your Android application, use the [Create OAuth2 Session](https://appwrite.io/docs/client/account?sdk=android-java#accountCreateOAuth2Session) endpoint. + +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]"); // Your project ID + +Account account = new Account(client); + +account.createOAuth2Session( + "spotify", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); +``` + +### iOS (Swift) +In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`. Be sure to replace the `[PROJECT_ID]` string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in your Appwrite console. + +```xml +CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + io.appwrite + CFBundleURLSchemes + + appwrite-callback-[PROJECT_ID] + + + +``` + +If you're using UIKit, you'll also need to add a hook to your `SceneDelegate.swift` file to ensure cookies work correctly. +```swift +func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + guard let url = URLContexts.first?.url, + url.absoluteString.contains("appwrite-callback") else { + return + } + WebAuthComponent.handleIncomingCookie(from: url) +} +``` + +To authenticate a user in your iOS application, use the [Create OAuth2 Session](https://appwrite.io/docs/client/account?sdk=apple-default#accountCreateOAuth2Session) endpoint. + +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]") // Your project ID + +let account = Account(client) + +let success = try await account.createOAuth2Session(provider: "spotify") +``` + +## Refreshing the OAuth2 session +OAuth2 sessions expire to protect from security risks. This means, OAuth2 sessions should be refreshed to keep the user authenticated. You can do this by calling the [Update OAuth Session](https://appwrite.io/docs/client/account#accountUpdateSession) endpoint when ever your user visits your app. + +### Web +```js +import { Client, Account } from "appwrite"; + +const client = new Client(); + +const account = new Account(client); + +client + .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint + .setProject('[PROJECT_ID]') // Your project ID +; + +// Updates current session +const promise = account.updateSession('current'); + +promise.then(function (response) { + console.log(response); // Success +}, function (error) { + console.log(error); // Failure +}); +``` + +### Flutter +```dart +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = new Client(); + final account = new Account(client); + + client + .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint + .setProject('[PROJECT_ID]'); // YOUR PROJECT ID + + // Simplest implementation of updating an OAuth2 session + // prints Session Object value on success and error message on failure + try { + final future = await account.updateSession(sessionId: 'current'); + print(future.toMap()); // Success + } on AppwriteException catch(e){ + print(e.message); // Failure + } +} +``` + +### Android (Kotlin) +```kotlin +import io.appwrite.Client +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]") // Your project ID + +val account = Account(client) + +val response = account.updateSession(sessionId = "current") +``` + +### Android (Java) +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]"); // Your project ID + +Account account = new Account(client); + +account.updateSession( + "current" + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); +``` + +### iOS (Swift) +``` swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("[PROJECT_ID]") // Your project ID + +let account = Account(client) + +let session = try await account.updateSession(sessionId: "current") +``` \ No newline at end of file From a828b0ae8022f81ed3432bfe66433260a8735418 Mon Sep 17 00:00:00 2001 From: Asutosh Ranjan Date: Thu, 3 Aug 2023 19:39:57 +0530 Subject: [PATCH 2/4] comments aligned --- app/views/docs/oauth-providers/spotify.md | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/docs/oauth-providers/spotify.md b/app/views/docs/oauth-providers/spotify.md index b66d80b9b..ae8a07934 100644 --- a/app/views/docs/oauth-providers/spotify.md +++ b/app/views/docs/oauth-providers/spotify.md @@ -36,7 +36,7 @@ const account = new Account(client); client .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint - .setProject('[PROJECT_ID]') // Your project ID + .setProject('[PROJECT_ID]') // Your Project ID ; // Go to Spotify OAuth login page @@ -99,7 +99,7 @@ void main() async { client .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint - .setProject('[PROJECT_ID]') // YOUR PROJECT ID + .setProject('[PROJECT_ID]') // YOUR PROJECT ID ; // OAuth Login, for simplest implementation you can leave both success and @@ -140,7 +140,7 @@ import io.appwrite.services.Account val client = Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your project ID + .setProject("[PROJECT_ID]") // Your Project ID val account = Account(client) @@ -179,7 +179,7 @@ import io.appwrite.services.Account; Client client = new Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]"); // Your project ID + .setProject("[PROJECT_ID]"); // Your Project ID Account account = new Account(client); @@ -233,7 +233,7 @@ import Appwrite let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your project ID + .setProject("[PROJECT_ID]") // Your Project ID let account = Account(client) @@ -253,7 +253,7 @@ const account = new Account(client); client .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint - .setProject('[PROJECT_ID]') // Your project ID + .setProject('[PROJECT_ID]') // Your Project ID ; // Updates current session @@ -262,7 +262,7 @@ const promise = account.updateSession('current'); promise.then(function (response) { console.log(response); // Success }, function (error) { - console.log(error); // Failure + console.log(error); // Failure }); ``` @@ -276,7 +276,7 @@ void main() async { client .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint - .setProject('[PROJECT_ID]'); // YOUR PROJECT ID + .setProject('[PROJECT_ID]'); // YOUR PROJECT ID // Simplest implementation of updating an OAuth2 session // prints Session Object value on success and error message on failure @@ -284,7 +284,7 @@ void main() async { final future = await account.updateSession(sessionId: 'current'); print(future.toMap()); // Success } on AppwriteException catch(e){ - print(e.message); // Failure + print(e.message); // Failure } } ``` @@ -296,7 +296,7 @@ import io.appwrite.services.Account val client = Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your project ID + .setProject("[PROJECT_ID]") // Your Project ID val account = Account(client) @@ -311,7 +311,7 @@ import io.appwrite.services.Account; Client client = new Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]"); // Your project ID + .setProject("[PROJECT_ID]"); // Your Project ID Account account = new Account(client); @@ -334,7 +334,7 @@ import Appwrite let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your project ID + .setProject("[PROJECT_ID]") // Your Project ID let account = Account(client) From 67efae9ffa7015f518ab6e1d164ecd7bfd70a621 Mon Sep 17 00:00:00 2001 From: Asutosh Ranjan Date: Thu, 3 Aug 2023 19:44:36 +0530 Subject: [PATCH 3/4] suggestions from review Co-authored-by: Steven <1477010+stnguyen90@users.noreply.github.com> --- app/views/docs/oauth-providers/spotify.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/docs/oauth-providers/spotify.md b/app/views/docs/oauth-providers/spotify.md index ae8a07934..07568ddd3 100644 --- a/app/views/docs/oauth-providers/spotify.md +++ b/app/views/docs/oauth-providers/spotify.md @@ -12,11 +12,11 @@ Before you can use Spotify to authenticate users, you need to enable the provide Don't close this modal, we'll need to create a Spotify app to complete this form. ## Creating a Spotify app for OAuth -To use Spotify OAuth with Appwrite, you need to create a Spotify app using a Spotify developer account. You can do this by following the [Creating Spotify App](https://developer.spotify.com/documentation/web-api/concepts/apps) guide, in the [Spotify Dashboard](https://developer.spotify.com/dashboard). While creating a new Spotify app in the **Redirect URI** filed, provide the **URI** found in the **Spotify OAuth2 Settings** modal from your Appwrite console. +To use Spotify OAuth with Appwrite, you need to create a Spotify app using a Spotify developer account. You can do this by following the [Creating Spotify App](https://developer.spotify.com/documentation/web-api/concepts/apps) guide, in the [Spotify Dashboard](https://developer.spotify.com/dashboard). When prompted to provide a **Redirect URI**, provide the **URI** found in the **Spotify OAuth2 Settings** modal from your Appwrite console. After you've created your Spotify app, you can head back to your Appwrite console to complete the form in the **Spotify OAuth2 Settings** modal. - You can find the **Client ID** in your Spotify app settings menu and provide this in the **App ID** field in the **Spotify OAuth2 Settings** modal from the Appwrite console. -- In the settings menu click on the **View client secret** button to get your apps client secret. +- In the settings for your Spotify app, click on **View client secret** to get your app's client secret. - Copy the client secret and provide this in the **App Secret** field in the **Spotify OAuth2 Settings** modal from the Appwrite console. ## Authenticating From 5377c924001945163c438807879bd4bbb8fee884 Mon Sep 17 00:00:00 2001 From: Asutosh Ranjan Date: Sat, 12 Aug 2023 12:21:51 +0000 Subject: [PATCH 4/4] aligned comments --- app/views/docs/oauth-providers/spotify.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/docs/oauth-providers/spotify.md b/app/views/docs/oauth-providers/spotify.md index 07568ddd3..90a41447c 100644 --- a/app/views/docs/oauth-providers/spotify.md +++ b/app/views/docs/oauth-providers/spotify.md @@ -36,7 +36,7 @@ const account = new Account(client); client .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint - .setProject('[PROJECT_ID]') // Your Project ID + .setProject('[PROJECT_ID]') // Your Project ID ; // Go to Spotify OAuth login page @@ -99,7 +99,7 @@ void main() async { client .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint - .setProject('[PROJECT_ID]') // YOUR PROJECT ID + .setProject('[PROJECT_ID]') // YOUR PROJECT ID ; // OAuth Login, for simplest implementation you can leave both success and @@ -140,7 +140,7 @@ import io.appwrite.services.Account val client = Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your Project ID + .setProject("[PROJECT_ID]") // Your Project ID val account = Account(client) @@ -179,7 +179,7 @@ import io.appwrite.services.Account; Client client = new Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]"); // Your Project ID + .setProject("[PROJECT_ID]"); // Your Project ID Account account = new Account(client); @@ -233,7 +233,7 @@ import Appwrite let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your Project ID + .setProject("[PROJECT_ID]") // Your Project ID let account = Account(client) @@ -253,7 +253,7 @@ const account = new Account(client); client .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint - .setProject('[PROJECT_ID]') // Your Project ID + .setProject('[PROJECT_ID]') // Your Project ID ; // Updates current session @@ -276,7 +276,7 @@ void main() async { client .setEndpoint('https://cloud.appwrite.io/v1') // YOUR API Endpoint - .setProject('[PROJECT_ID]'); // YOUR PROJECT ID + .setProject('[PROJECT_ID]'); // YOUR PROJECT ID // Simplest implementation of updating an OAuth2 session // prints Session Object value on success and error message on failure @@ -296,7 +296,7 @@ import io.appwrite.services.Account val client = Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your Project ID + .setProject("[PROJECT_ID]") // Your Project ID val account = Account(client) @@ -311,7 +311,7 @@ import io.appwrite.services.Account; Client client = new Client(context) .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]"); // Your Project ID + .setProject("[PROJECT_ID]"); // Your Project ID Account account = new Account(client); @@ -334,7 +334,7 @@ import Appwrite let client = Client() .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint - .setProject("[PROJECT_ID]") // Your Project ID + .setProject("[PROJECT_ID]") // Your Project ID let account = Account(client)