diff --git a/app/views/docs/authentication-anonymous.phtml b/app/views/docs/authentication-anonymous.phtml new file mode 100644 index 000000000..a64394aca --- /dev/null +++ b/app/views/docs/authentication-anonymous.phtml @@ -0,0 +1,120 @@ +
+ Anonymous sessions allow you to implement guest users. + Guest users let you store user information like items in their cart or theme preferences before they create an account. + This reduces the friction for your users to get started with your app. +
+ ++ If a user later creates an account, their information will be inherited by the newly created account. +
+ ++ Create an anonymous session with Create Anonymous Session route. +
+ + +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const promise = account.createAnonymousSession();
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = await account.createAnonymousSession();
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val user = account.createAnonymousSession()
+ 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 user = try await account.createAnonymousSession()
+
+mutation {
+ accountCreateAnonymousSession {
+ _id
+ userId
+ provider
+ expire
+ }
+}
+ + Anonymous users cannot sign back in. + If the session expires, they move to another computer, or they clear their browser data, they won't be able to log in again. + Remember to prompt the user to create an account to not lose their data. +
+ ++ Create an account with any of these methods to transition from an anonymous session to a user account session. +
+ + + ++Phone (SMS) +
++Magic URL +
++OAuth2 +
diff --git a/app/views/docs/authentication-email-pass.phtml b/app/views/docs/authentication-email-pass.phtml new file mode 100644 index 000000000..8fde1db9a --- /dev/null +++ b/app/views/docs/authentication-email-pass.phtml @@ -0,0 +1,649 @@ ++ Email and password login is the most commonly used authentication method. + Appwrite Authentication promotes a safer internet by providing secure APIs and promoting better password choices to end users. + Appwrite supports added security features like blocking personal info in passwords, password dictionary, and password history to help users choose good passwords. +
+ ++ You can use the Appwrite Client SDKs to create an account using email and password. +
+ +import { Client, Account, ID } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const promise = account.create('[USER_ID]', 'email@example.com', '');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = await account.create(
+ userId: ID.unique(),
+ email: 'email@example.com',
+ password: 'password',
+);
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+import io.appwrite.ID
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val user = account.create(
+ userId = ID.unique(),
+ email = "email@example.com",
+ password = "password"
+)
+ 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 user = try await account.create(
+ userId: ID.unique(),
+ email: "email@example.com",
+ password: "password"
+)
+
+mutation {
+ accountCreate(userId: "unique()", email: "email@example.com", password: "password") {
+ _id
+ email
+ name
+ }
+}
+ + Passwords are hashed with Argon2, a resilient and secure password hashing algorithm. +
+ +
+ After an account is created, it can be verified through the account create verification route.
+ The user doesn't need to be verified to log in, but you can restrict resource access to verified users only using permissions through the user([USER_ID], "verified")
role.
+
+ First, send a verification email.
+ Specify a redirect URL which users will be redirected to.
+ The verification secrets will be appended as query parameters to the redirect URL.
+ In this example, the redirect URL is https://example.com/verify
.
+
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('5df5acd0d48c2') // Your project ID
+;
+
+const promise = account.createVerification('https://example.com');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.createVerification(
+ url: 'https://example.com',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+
+ import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import io.appwrite.Client
+import io.appwrite.services.Account
+
+class MainActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ val client = Client(applicationContext)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+ val account = Account(client)
+
+ GlobalScope.launch {
+ val response = account.createVerification(
+ url = "https://example.com"
+ )
+ val json = response.body?.string()
+ }
+ }
+}
+ import Appwrite
+
+func main() async throws {
+ let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ let account = Account(client)
+ let token = try await account.createVerification(
+ url: "https://example.com"
+ )
+
+ print(String(describing: token)
+}
+ mutation {
+ accountCreateVerification(
+ url: "https://example.com"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+
+ Next, implement the verification page in your app.
+ This page will parse the secrets passed in through the userId
and secret
query parameters.
+ In this example, the code below will be found in the page served at https://example.com/verify
.
+
+ Since the secrets are passed in through url params, it will be easiest to perform this step in the browser. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const urlParams = new URLSearchParams(window.location.search);
+const secret = urlParams.get('secret');
+const userId = urlParams.get('userId');
+
+const promise = account.updateVerification(userId, secret);
+
+promise.then(function (response) {
+ console.log(response);
+}, function (error) {
+ console.log(error);
+});
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.updateVerification(
+ userId: '[USER_ID]',
+ secret: '[SECRET]',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+val account = Account(client)
+
+val response = account.updateVerification(
+ userId = "[USER_ID]",
+ secret = "[SECRET]"
+)
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let token = try await account.updateVerification(
+ userId: "[USER_ID]",
+ secret: "[SECRET]"
+)
+ mutation {
+ accountUpdateVerification(
+ userId: "[USER_ID]",
+ secret: "[SECRET]"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+ + After you've created your account, users can be logged in using the Create Email Session route. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const promise = account.createEmailSession('email@example.com', 'password');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final session = await account.createEmailSession(
+ email: 'email@example.com',
+ password: 'password'
+);
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val session = account.createEmailSession(
+ email = "email@example.com",
+ password = "password"
+)
+
+ 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.createEmailSession(
+ email: "email@example.com",
+ password: "password"
+)
+
+ mutation {
+ accountCreateEmailSession(email: "email@example.com", password: "password") {
+ _id
+ userId
+ provider
+ expire
+ }
+}
+ + If a user forgets their password, they can initiate a password recovery flow to recover their password. The Create Password Recovery endpoint sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link, they are redirected back to the password reset URL with the secret key and email address values attached to the URL as query strings. +
+ ++ Only redirect URLs to domains added as a platform on your Appwrite console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const promise = account.createRecovery('email@example.com', 'https://example.com');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = account.createRecovery(
+ email: 'email@example.com',
+ url: 'https://example.com',
+);
+
+ 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.createRecovery(
+ email = "email@example.com",
+ url = "https://example.com"
+)
+
+ 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 token = try await account.createRecovery(
+ email: "email@example.com",
+ url: "https://example.com"
+)
+
+ mutation {
+ accountCreateRecovery(
+ email: "email@example.com",
+ url: "https://example.com"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+ +After receiving an email with the secret attached to the redirect link, submit a request to the Create Password Recovery (confirmation) endpoint to complete the recovery flow. The verification link sent to the user's email address is valid for 1 hour. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const promise = account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = await account.updateRecovery(
+ userId: '[USER_ID]',
+ secret: '[SECRET]',
+ password: 'password'
+ passwordAgain: 'password'
+);
+
+ 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 token = account.updateRecovery(
+ userId = "[USER_ID]",
+ secret = "[SECRET]",
+ password = "password",
+ passwordAgain = "password"
+)
+
+ 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 token = try await account.updateRecovery(
+ userId: "[USER_ID]",
+ secret: "[SECRET]",
+ password: "password",
+ passwordAgain: "password"
+)
+
+ mutation {
+ accountUpdateRecovery(
+ userId: "[USER_ID]",
+ secret: "[SECRET]",
+ password: "password",
+ passwordAgain: "password"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+ + Appwrite's security first mindset goes beyond a securely implementated of authentication API. + You can enable features like password dictionary, password history, and disallow personal data in passwords to encourage users to pick better passwords. + By enabling these features, you protect user data and teach better password choices, which helps make the internet a safer place. +
++ + Learn more about security features + +
\ No newline at end of file diff --git a/app/views/docs/authentication-magic.phtml b/app/views/docs/authentication-magic.phtml new file mode 100644 index 000000000..0c25a3a0d --- /dev/null +++ b/app/views/docs/authentication-magic.phtml @@ -0,0 +1,98 @@ ++ Magic URL is a password-less way to authenticate users. + When a user logs in by providing their email, they will receive an email with a "magic" link that contains a secret used to log in the user. + The user can simply click the link to be logged in. +
+ ++ Initialize the log in process with the Create Magic URL Session route. + If the email has never been used, a new account is generated, then the user will receive an email. + If the email is already attached to an account, the user ID is ignored and the user will receive a link in their email. +
+ +import { Client, Account, ID } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+
+const promise = account.createMagicURLSession(ID.unique(), 'email@example.com');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ mutation {
+ accountCreateMagicURLSession(
+ userId: "ID.unique()",
+ email: "email@example.com"
+ ) {
+ _id
+ _createdAt
+ userId
+ secret
+ expire
+ }
+}
+ + After receiving your secret from an email, you can create a session. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const urlParams = new URLSearchParams(window.location.search);
+const secret = urlParams.get('secret');
+const userId = urlParams.get('userId');
+
+const user = await account.updateMagicURLSession(userId, secret);
+ mutation {
+ accountUpdateMagicURLSession(
+ userId: "unique()",
+ secret: "[SECRET]"
+ ) {
+ _id
+ _createdAt
+ userId
+ expire
+ provider
+ }
+}
+ + Appwrite has built-in features to help manage user accounts. + Users can be organized into teams and be given labels, so they can be given different permissions and access different resources. + Each user can also have their own preference object, which you can use to save preferences such as theme, language, and notification settings. +
+ + ++ You can store user preferences on a user's account using Appwrite's Update Preferences endpoint. + You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices. +
++ Preferences are stored as a key-value JSON object. + The maximum allowed size for preferences is 64kB, and an error will be thrown if this limit is exceeded. +
+import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const promise = account.updatePrefs({darkTheme: true, language: 'en'});
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final user = await account.updatePrefs(
+ prefs: {
+ "darkTheme": true,
+ "language": "en",
+ }
+);
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val user = account.updatePrefs(
+ prefs = mapOf("darkTheme" to true, "language" to "en")
+)
+
+ 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 user = try await account.updatePrefs(
+ prefs: ["darkTheme": true, "language": "en"]
+)
+
+ mutation {
+ accountUpdatePrefs(
+ prefs: "{\"darkTheme\": true, \"language\": \"en\"}"
+ ) {
+ _id
+ name
+ prefs {
+ data
+ }
+ }
+}
+ After a user's preferences are updated, they can be retrieved using the Get Preferences endpoint.
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const promise = account.getPrefs();
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final prefs = await account.getPrefs();
+
+ 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 prefs = account.getPrefs()
+
+ 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 prefs = try await account.getPrefs()
+
+ query {
+ accountGetPrefs {
+ data
+ }
+}
+ + The Users API is a dedicated API for managing users from an admin's perspective. + You'll notice that the Account API doesn't allow you to view or make changes to other users. + This is by design and for security reasons. +
+ ++ You can use the Users API with an API key authenticated Server SDK to manage users. + If you must expose parts of the Users API to normal users, we suggest doing so through an Appwrite Function. + Exposing API keys to users is dangerous and a security risk, by using an Appwrite Function, you can add your own validation to prevent malicious behavior. +
+ ++ + Learn more about the Users API + +
+ +
+ Labels are a good way to flag a user to grant them access to resources.
+ For example, a subscriber
label can be added to a user once they've purchased a subscription.
+
const sdk = require('node-appwrite');
+
+// Init SDK
+const client = new sdk.Client();
+
+const users = new sdk.Users(client);
+
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ use Appwrite\Client;
+use Appwrite\Services\Users;
+use Appwrite\Role;
+
+$client = new Client();
+
+$client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+$users = new Users($client);
+
+$result = $users->updateLabels(
+ '[USER_ID]',
+ [
+ Role.label('subscriber'),
+ ]
+);
+ from appwrite.client import Client
+from appwrite.services.users import Users
+from appwrite.role import Role
+
+client = Client()
+
+(client
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+)
+
+users = Users(client)
+
+result = users.update_labels('[USER_ID]', [ Role.label('subscriber') ])
+ require 'Appwrite'
+
+include Appwrite
+
+client = Client.new
+ .set_endpoint('https://cloud.appwrite.io/v1') # Your API Endpoint
+ .set_project('5df5acd0d48c2') # Your project ID
+ .set_key('919c2d18fb5d4...a2ae413da83346ad2') # Your secret API key
+
+users = Users.new(client)
+
+response = users.update_labels(user_id: '[USER_ID]', labels: [ Role.label('subscriber') ])
+
+puts response.inspect
+ import * as sdk from "https://deno.land/x/appwrite/mod.ts";
+
+// Init SDK
+let client = new sdk.Client();
+
+let users = new sdk.Users(client);
+
+client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+;
+
+
+const promise = users.updateLabels('[USER_ID]', [ Role.label('subscriber') ]);
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:dart_appwrite/dart_appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Users users = Users(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
+ ;
+
+ Future result = users.updateLabels(
+ userId: '[USER_ID]',
+ labels: [ Role.label('subscriber') ],
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+ import io.appwrite.Client
+import io.appwrite.services.Users
+import io.appwrite.Role
+
+suspend fun main() {
+ val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+
+ val users = Users(client)
+ val response = users.updateLabels(
+ userId = "[USER_ID]",
+ labels = [ Role.label('subscriber') ]
+ )
+ val json = response.body?.string()
+}
+ import Appwrite
+
+func main() async throws {
+ let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+ .setKey("919c2d18fb5d4...a2ae413da83346ad2") // Your secret API key
+ let users = Users(client)
+ let response = try await users.updateLabels(
+ userId: "[USER_ID]",
+ labels: [ Role.label('subscriber') ]
+ )
+
+ print(String(describing: response)
+}
+
+
+ This would correspond with the permissions Permissions.read(Role.label('subscriber'))
, Permissions.update(Role.label('subscriber'))
, Permissions.delete(Role.label('subscriber'))
, and Permissions.create(Role.label('subscriber'))
.
+
+ Learn more about permissions +
+ ++ Teams are a good way to allow users to share access to resources. +
+ ++ For example, in a todo app, a user can create a team for one of their todo lists and invite another user to the team to grant the other user access. + The invited user can accept the invitation to gain access. + If the user's ever removed from the team, they'll lose access again. +
diff --git a/app/views/docs/authentication-oauth.phtml b/app/views/docs/authentication-oauth.phtml new file mode 100644 index 000000000..53b77ae2d --- /dev/null +++ b/app/views/docs/authentication-oauth.phtml @@ -0,0 +1,379 @@ ++ OAuth authentication allows users to log in using accounts from other popular services. + This can be convenient for users because they can start using your app without creating a new account. + It can also be more secure, because the user has one less password that could become vulnerable. +
+ ++ When using OAuth to authenticate, the authentication request is initiated from the client application. + The user is then redirected to an OAuth 2 provider to complete the authentication step, and finally, the user is redirected back to the client application. +
+ ++ Before using OAuth 2 login, you need to enable and configure an OAuth 2 login provider. +
+ ++ To initialize the OAuth 2 login process, use the Create OAuth 2 Session route. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+// Go to OAuth provider login page
+account.createOAuth2Session('amazon', [LINK_ON_SUCCESS], [LINK_ON_FAILURE]);
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+// Go to OAuth provider login page
+await account.createOAuth2Session(provider: 'amazon');
+ In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the <application>
tag, along side the existing <activity>
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.
escape('
+ ...
+
+ ...
+
+
+
+
+
+
+
+
+
+
+ '); ?>
+
+import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+// Go to OAuth provider login page
+account.createOAuth2Session(provider = "amazon")
+ In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your Info.plist
.
escape('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.
escape('
+func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
+ guard let url = URLContexts.first?.url,
+ url.absoluteString.contains("appwrite-callback") else {
+ return
+ }
+ WebAuthComponent.handleIncomingCookie(from: url)
+}
+');?>
+import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+let account = Account(client)
+
+// Go to OAuth provider login page
+try await account.createOAuth2Session(provider: "amazon")
+ OAuth 2 is not available through the GraphQL API. You can use the REST API or any Client SDK instead.
++ You'll be redirected to the OAuth 2 provider's login page to log in. + Once complete, your user will be redirected back to your app. +
+ +
+ You can optionally configure success
or failure
redirect links on web to handle success and failure scenarios.
+
+After authenticating a user through their OAuth 2 provider, you can fetch their profile information such as their avatar image or name. +To do this you can use the access token from the OAuth 2 provider and make API calls to the provider. +
+ ++After creating an OAuth 2 session, you can fetch the session to get information about the provider. +
+ +import { Client, Account } from "appwrite";
+
+const client = new Client();
+
+const account = new Account(client);
+
+const session = await account.getSession('current');
+
+// Provider information
+console.log(session.provider);
+console.log(session.providerUid);
+console.log(session.providerAccessToken);
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final session = await getSession(
+ sessionId : "[SESSION_ID]"
+);
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.providerAccessToken);
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+val account = Account(client)
+
+val response = account.getSession(
+ sessionId = "[SESSION_ID]"
+)
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.providerAccessToken);
+
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let session = try await account.getSession(
+ sessionId: "[SESSION_ID]"
+)
+
+// Provider information
+print(session.provider);
+print(session.providerUid);
+print(session.providerAccessToken);
+
+
+
++ An OAuth 2 session will have the following attributes. +
+ +property | +Description | +
provider | +The OAuth2 Provider. | +
providerUid | +User ID from the OAuth 2 Provider. | +
providerAccessToken | +Access token from the OAuth 2 provider. Use this to make requests to the OAuth 2 provider to fetch personal data. | +
providerAccessTokenExpiry | +Check this value to know if an access token is about to expire. | +
+ You can use the providerAccessToken
to make requests to your OAuth 2 provider.
+ Refer to the docs for the OAuth 2 provider you're using to learn about making API calls with the access token.
+
+ OAuth 2 sessions expire to protect from security risks.
+ OAuth 2 sessions should be refreshed periodically, so access tokens don't expire.
+ Check value of providerAccessTokenExpiry
to know if the token is expired or is about to expire.
+ Refreshing before every request might cause rate limit problems.
+ You can do this by calling the Update OAuth Session endpoint when ever your user visits your app.
+
const promise = account.updateSession('[SESSION_ID]');
+
+promise.then(function (response) {
+ console.log(response); // Success
+}, function (error) {
+ console.log(error); // Failure
+});
+ import 'package:appwrite/appwrite.dart';
+
+void main() { // Init SDK
+ Client client = Client();
+ Account account = Account(client);
+
+ client
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('5df5acd0d48c2') // Your project ID
+ ;
+ Future result = account.updateSession(
+ sessionId: '[SESSION_ID]',
+ );
+
+ result
+ .then((response) {
+ print(response);
+ }).catchError((error) {
+ print(error.response);
+ });
+}
+ import io.appwrite.Client
+import io.appwrite.services.Account
+
+val client = Client(context)
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+val account = Account(client)
+
+val response = account.updateSession(
+ sessionId = "[SESSION_ID]"
+)
+ import Appwrite
+
+let client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("5df5acd0d48c2") // Your project ID
+
+let account = Account(client)
+
+let session = try await account.updateSession(
+ sessionId: "[SESSION_ID]"
+)
+ OAuth 2 is not available through the GraphQL API. You can use the REST API or any Client SDK instead.
+Only keep user sessions active as long as needed and only maintain one instance of the Client SDK in your app to avoid conflicting session data.
+Only keep user sessions active as long as needed and maintain exactly one instance of the Client SDK in your app to avoid conflicting session data.
In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit deletes the oldest session.
+In Appwrite versions 1.2 and above, you can limit the number of active sessions created per user to prevent the accumulation of unused but active sessions. New sessions created by the same user past the session limit delete the oldest session.
You can change the session limit in the Security tab of the Auth Service in your Appwrite Console. The default session limit is 10 with a maximum configurable limit of 100.
-- Security is very important to protect users' data and privacy. Appwrite uses a permissions model coupled with user sessions to ensure users need correct permissions to access resources. With all Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level. These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key. + Security is very important to protect users' data and privacy. + Appwrite uses a permissions model coupled with user sessions to ensure users need correct permissions to access resources. + With all Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level. + These permissions are enforced for client SDKs and server SDKs when using JWT, but are ignored when using a server SDK with an API key.
-Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password everytime it's changed.
+Password history prevents users from reusing recent passwords. This protects user accounts from security risks by enforcing a new password every time it's changed.
Password history can be enabled in the Auth service's Security tab on the Appwrite console. You can choose how many previous passwords to remember up to a maximum of 20 and block users from reusing them.
-Password dictionary protects users from using bad passwords. It compares the user's password to the 10,000 most common passwords and throws an error if there's a match. Together with rate limits, password dictionary will significantly reduce the chance of a malicious actor from guessing user passwords.
+Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
-Password dictionary can be enabled in the Auth service's Security tab on the Appwrite console.
\ No newline at end of file ++ Encourage passwords that are hard to guess by disallowing users to pick passwords that contain personal data. + Personal data includes the user's name, email, and phone number. +
+Disallowing personal data can be enabled in the Auth service's Security tab on the Appwrite Console.
diff --git a/app/views/docs/authentication-server.phtml b/app/views/docs/authentication-server.phtml index 186b5eb5b..de1c90211 100644 --- a/app/views/docs/authentication-server.phtml +++ b/app/views/docs/authentication-server.phtml @@ -7,12 +7,12 @@Before making requests to your backend APIs, your client application needs to first create a session directly with Appwrite using the account service. This session will act like an ID card for the user and can be used to access resources in Appwrite. The client will only receive information accessible to the user based on the resources's permissions.
+Before making requests to your backend APIs, your client application needs to first create a session directly with Appwrite using the account service. This session will act like an ID card for the user and can be used to access resources in Appwrite. The client will only receive information accessible to the user based on the resources' permissions.
When you build backend APIs to extend Appwrite's functionality, these APIs should still respect access permissions to keep user data secure. Appwrite's backend SDKs allows you to securely act on behalf of a user with the same permissions by using JWT authentication.
JSON Web Tokens (JWTs) are a secure means to transfer information or claims between two parties. JWT act like temporary copies of the user's ID card that allow Appwrite's Server SDKs to access information oh behalf of a user.
+JSON Web Tokens (JWTs) are a secure means to transfer information or claims between two parties. JWTs act like temporary copies of the user's ID card that allow Appwrite's Server SDKs to access information on behalf of a user.
You need to create a session using the Client SDKs before generating a JWT. The JWT will be a stateless proof of claim for the identity of the authenticated user and expire after 15 minutes or when the session is deleted.
@@ -26,17 +26,11 @@ const client = new Client() .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint - .setProject('[PROJECT_ID]'); // Your project ID + .setProject('[PROJECT_ID]'); // Your project ID const account = new Account(client); -const promise = account.createJWT(); - -promise.then(function (response) { - console.log(response); -}, function (error) { - console.log(error); -}); +const user = await account.createJWT();Only the birthday of Kevin is returned and documents where user-A
has no permissions to access are not returned.
Only Kevin's birthday is returned and documents where user-A
has no permissions to access are not returned.
{
"total": 1,
@@ -467,7 +461,7 @@ var documentList = await databases.ListDocuments(
}
If the same request is made where the Server SDK's client
is authenticate with an API key instead of a JWT, the results returned will be different.
If the same request is made where the Server SDK's client
is authenticated with an API key instead of a JWT, the results returned will be different.
+ Phone authentication lets users create accounts using their phone numbers and log in through SMS messages. +
+ + ++ Phone authentication is done using a two-step authentication process. + When using phone authentication, the authentication request is initiated from the client application and an SMS message is sent to the user's phone. + The SMS message will contain a secret the user can use to log in. +
+ ++ Send an SMS message to initiate the authentication process. + A new account will be created for this phone number if it has never been used before. +
+ +import { Client, Account, ID } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const sessionToken = await account.createPhoneSession(
+ ID.unique(),
+ '+14255550123'
+);
+
+var userId = sessionToken.userId; // Store this somewhere to use later when logging in
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final sessionToken = await account.createPhoneSession(
+ userId: ID.unique(),
+ phone: '+14255550123'
+);
+
+final userId = sessionToken.userId; // Store this somewhere to use later when logging in
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+import io.appwrite.ID
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val sessionToken = account.createPhoneSession(
+ userId = ID.unique(),
+ phone = "+14255550123"
+)
+
+val userId = sessionToken.userId // Store this somewhere to use later when logging in
+
+ 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 sessionToken = try await account.createPhoneSession(
+ userId: ID.unique(),
+ phone: "+14255550123"
+)
+
+let userId = sessionToken.userId // Store this somewhere to use later when logging in
+
+ mutation {
+ accountCreatePhoneSession(userId: "unique()", phone: "+14255550123") {
+ _id
+ userId
+ secret
+ expire
+ }
+}
+ + After initiating the phone authentication process, the returned user ID and secret are used to confirm the user. + The secret will usually be a 6-digit number in the SMS message sent to the user. +
+ +import { Client, Account, ID } from "appwrite";
+
+const client = new Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+const account = new Account(client);
+
+const session = await account.updatePhoneSession(
+ userId, // From when you called createPhoneSession
+ '[SECRET]' // The 6-digit code from the SMS message
+);
+
+ import 'package:appwrite/appwrite.dart';
+
+final client = Client()
+ .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
+ .setProject('[PROJECT_ID]'); // Your project ID
+
+final account = Account(client);
+
+final session = await account.updatePhoneSession(
+ userId: userId, // From when you called createPhoneSession
+ secret: '[SECRET]' // The 6-digit code from the SMS message
+);
+
+ import io.appwrite.Client
+import io.appwrite.services.Account
+import io.appwrite.ID
+
+val client = Client()
+ .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
+ .setProject("[PROJECT_ID]") // Your project ID
+
+val account = Account(client)
+
+val session = account.updatePhoneSession(
+ userId = userId, // From when you called createPhoneSession
+ secret = "[SECRET]" // The 6-digit code from the SMS message
+)
+
+ 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.updatePhoneSession(
+ userId: userId, // From when you called createPhoneSession
+ secret: "[SECRET]" // The 6-digit code from the SMS message
+)
+
+
+mutation {
+ accountUpdatePhoneSession(userId: "[USER_ID]", secret: "[SECRET]") {
+ _id
+ userId
+ provider
+ expire
+ }
+}
+ + After the secret is verified, a session will be created. +
\ No newline at end of file diff --git a/app/views/docs/authentication.phtml b/app/views/docs/authentication.phtml index 9910bc286..05e44aa9c 100644 --- a/app/views/docs/authentication.phtml +++ b/app/views/docs/authentication.phtml @@ -1,37 +1,16 @@- Appwrite provides authentication for many different use cases to fit the needs of developers. - Appwrite manages authentication with a combination of accounts and sessions. - Accounts can be created in many different ways, such as through an anonymous session, email and password, OAuth authentication, magic URLs, and more. -
- -- The Account API operates in the scope of the currently logged-in account and is usually used in a frontend or mobile app. The Users API is used in backend integrations and uses an API key with access to all your project users. -
- -- Some of the Account API methods are available from Server SDKs when you authenticate with a JWT. This allows your Server SDK to perform actions on behalf of a user. -
- -- A user account in Appwrite is the primary way to access information for a given project. Accounts can be created in many different ways, including email & password, anonymous sessions, OAuth2, phone authentication, and more. Applications can create and manage sessions through the REST API or Client SDKs. -
- -- Creating an account via email and password is one of the most common ways to sign up for an application. Appwrite provides email and password authentication out of the box. Using one of Appwrite's Client SDKs, or the REST APIs directly, you can create an account using an email address and password in your application. + Appwrite Authentication delivers more than just user sign up and log in. + Authentication makes it easy to build secure and robust authentication with support for many different authentication methods.
- Passwords are hashed with Argon2, a resilient and secure password hashing algorithm. + You can manage user accounts with user preferences, user labeling, or organizing users into teams. + Combined with a robust permissions system, Appwrite Authentication provides everything you need to authenticate and manage users.
+- The example below shows you how to create an account: + Adding Appwrite Authentication to your apps can be as easy as these lines of code.
mutation {
- accountCreate(userId: "unique()", email: "team@appwrite.io", password: "password") {
+ accountCreate(userId: "unique()", email: "email@example.com", password: "password") {
_id
email
name
@@ -130,1139 +103,78 @@ mutation {
- After an account is created, it can be verified through the account verification route provided by the Appwrite Accounts API. The user doesn't need to be verified to log in, but you can restrict resource access to verified users only using permissions.
+ Use email and password authentication as a starting point and explore the many powerful features of Appwrite authentication.
-Anonymous User
+Account vs Users API
-Anonymous authentication allows users of your application to create a temporary valid session without creating an account. The session has an expiration time of one year. If an account is created while an anonymous session is active, it will be attached to the existing anonymous session.
+ Appwrite has two auth APIs for different purposes, which are Account and Users.
+ Here's how you choose between the two, depending on your needs.
-
- -
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.createAnonymousSession();
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.createAnonymousSession();
-
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val user = account.createAnonymousSession()
-
-
- -
-
Apple
-
- import Appwrite
-
-let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-let account = Account(client)
+Account API
+
+ Use the Account API when acting on behalf of individual users when building client applications, like websites or mobile apps.
+ The Account API is authenticated through secure cookies that store session information, so Appwrite knows which authenticated user is accessing data.
+ The Account API is safe to expose to end users, because their access to data and resources is limited by Appwrite's permission system.
+
-let user = try await account.createAnonymousSession()
-
-
- -
-
GraphQL
-
-
-mutation {
- accountCreateAnonymousSession {
- _id
- userId
- provider
- expire
- }
-}
-
-
-
+Users API
+
+ Use the Users API when acting as an administrator in use cases like building admin consoles or server integrations.
+ The Users API uses API keys to authenticate, which means Appwrite only knows which API key is accessing data.
+ API keys don't respect permissions, which means they can access all data, and should never be shared with end users in client applications.
+ The Users API also has batch operations, letting you query and manage users from an admin's perspective.
+
-OAuth
+Explore
+Explore Appwrite Authentication's features.
- OAuth is another way to authenticate a user using a multistep process. When using OAuth to authenticate, the authentication request is initiated from the client application. The user is then redirected to an OAuth2 provider to complete the authentication step, and finally, the user is redirected back to the client application. This provides integration with many third-party services that provide their own OAuth integration as a more secure approach than providing a username/password directly.
+
+ Log in with email and password
+
- In applications with first-party redirects, using OAuth2 for authentication is preferred.
+
+ Log in with SMS messages
+
- The example below shows you how to authenticate with OAuth2 using Amazon's OAuth system.
+
+ Log in with Magic URL
+
-
- -
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-// Go to OAuth provider login page
-account.createOAuth2Session('amazon');
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-// Go to OAuth provider login page
-await account.createOAuth2Session(provider: 'amazon');
-
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-// Go to OAuth provider login page
-account.createOAuth2Session(provider = "amazon")
-
-
- -
-
Apple
-
- import Appwrite
-
-let client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-let account = Account(client)
-
-// Go to OAuth provider login page
-try await account.createOAuth2Session(provider: "amazon")
-
-
- -
-
GraphQL
-
- OAuth is not available through the GraphQL API. You can use the REST API or any Client SDK instead.
-
-
-
-
-
- If there is already an active anonymous session, the new session will be attached to it. If there are no active sessions, the server will attempt to look for an account with the same email address as the email received from the OAuth2 provider and attach the new session to the existing account. If no matching account is found - the server will create a new account.
+
-Phone
-
- Phone authentication is done using a two-step authentication process. When using phone authentication, the authentication request is initiated from the client application and an SMS is sent to the user with a secret key for creating a session.
+
+ Log in as a guest (anonymous)
+
- The example below shows you how to initiate a phone authentication request.
+
+ Manage users
+
-
- -
-
Web
-
- import { Client, Account, ID } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.createPhoneSession(
- ID.unique(),
- '+16171234567'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final session = await account.createPhoneSession(
- userId: ID.unique(),
- phone: '+16171234567'
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-import io.appwrite.ID
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val session = account.createPhoneSession(
- userId = ID.unique(),
- phone = "+16171234567"
-)
-
- -
-
Apple
-
- 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.createPhoneSession(
- userId: ID.unique(),
- phone: "+16171234567"
-)
-
- -
-
GraphQL
-
- mutation {
- accountCreatePhoneSession(userId: "unique()", phone: "+16171234567") {
- _id
- userId
- secret
- expire
- }
-}
-
-
-
-
- After initiation, the returned user ID and secret are used to confirm the user. The secret will be a 6-digit number in the SMS message sent to the user.
+
+ Server integrations
+
-
- -
-
Web
-
- import { Client, Account, ID } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.updatePhoneSession(
- '[USER_ID]',
- '[SECRET]'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final session = await account.updatePhoneSession(
- userId: '[USER_ID]',
- secret: '[SECRET]'
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-import io.appwrite.ID
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val session = account.updatePhoneSession(
- userId = "[USER_ID]",
- secret = "[SECRET]"
-)
-
- -
-
Apple
-
- 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.updatePhoneSession(
- userId: "[USER_ID]",
- secret: "[SECRET]"
-)
-
- -
-
GraphQL
-
-
-mutation {
- accountUpdatePhoneSession(userId: "[USER_ID]", secret: "[SECRET]") {
- _id
- userId
- provider
- expire
- }
-}
-
-
-
-
-
- After the secret is verified, a session will be created.
-
-
-
-Magic URL
-
- Magic URL authentication allows a user to sign in without a password. Magic URL authentication sends the user an email with a secret key for creating a new session. If the provided email does not belong to an existing user, the provided user ID is used to create a new user. If the account already exists, the provided user ID is ignored
-
-
-
- Only redirect URLs to domains added as a platform on your Appwrite console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
-
-
-
-
- Magic URL authentication can be initiated like this:
-
-
-
-
- -
-
Web
-
- import { Client, Account, ID } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.createMagicURLSession(ID.unique(), 'email@example.com');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.createMagicURLSession(
- userId: ID.unique(),
- email: 'email@example.com',
-);
-
- -
-
Android
-
- 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 user = account.createMagicURLSession(
- userId = ID.unique(),
- email = "email@example.com"
-)
-
- -
-
Apple
-
- 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 user = try await account.createMagicURLSession(
- userId: ID.unique(),
- email: "email@example.com"
-)
-
- -
-
GraphQL
-
- mutation {
- accountCreateMagicURLSession(
- userId: "unique()",
- email: "email@example.com"
- ) {
- _id
- _createdAt
- userId
- secret
- expire
- }
-}
-
-
-
-
-
- After receiving your secret from an email, you can create a new Magic URL session like this:
-
-
-
-
- -
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.updateMagicURLSession('[USER_ID]', '[SECRET]');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.updateMagicURLSession(
- userId: '[USER_ID]',
- secret: '[SECRET]',
-);
-
- -
-
Android
-
- 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 user = account.updateMagicURLSession(
- userId = '[USER_ID]',
- secret = '[SECRET]'
-)
-
- -
-
Apple
-
- 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 user = try await account.updateMagicURLSession(
- userId: '[USER_ID]',
- secret: "[SECRET]"
-)
-
- -
-
GraphQL
-
- mutation {
- accountUpdateMagicURLSession(
- userId: "[USER_ID]",
- secret: "[SECRET]"
- ) {
- _id
- _createdAt
- userId
- expire
- provider
- }
-}
-
-
-
-
-Login
-
-
- Logging in with an email and password is one of the most common ways to login into an application.
-
-
-
- The example below shows you how to create a session:
-
-
-
- -
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.createEmailSession(
- 'team@appwrite.io',
- 'password'
-);
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final session = await account.createEmailSession(
- email: 'team@appwrite.io',
- password: 'password'
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val session = account.createEmailSession(
- email = "team@appwrite.io",
- password = "password"
-)
-
- -
-
Apple
-
- 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.createEmailSession(
- email: "team@appwrite.io",
- password: "password"
-)
-
- -
-
GraphQL
-
- mutation {
- accountCreateEmailSession(email: "team@appwrite.io", password: "password") {
- _id
- userId
- provider
- expire
- }
-}
-
-
-
-
-
- When a user tries to access restricted resources, you can check if they have a valid, active session. The Account Service provides a get() method that checks whether the current user session is active and returns the account information if successful.
-
-
-
- The example below shows you how to check whether there is an active session:
-
-
-
- -
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.get();
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final session = await account.get();
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val session = account.get()
-
- -
-
Apple
-
- 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.get()
-
- -
-
GraphQL
-
- query {
- accountGet {
- _id
- email
- name
- status
- }
-}
-
-
-
-
-
- An authenticated session in Appwrite lasts for 1 year and is then automatically expired.
-
-
-
-Password Recovery
-
- If a user forgets their password, they can initiate a password recovery flow to recover their password. The Create Password Recovery endpoint sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link, they are redirected back to the password reset URL with the secret key and email address values attached to the URL as query strings.
-
-
-
- Only redirect URLs to domains added as a platform on your Appwrite console will be accepted. URLs not added as a platform are rejected to protect against redirect attacks.
-
-
-
--
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.createPasswordRecovery('email@example.com', 'https://example.com');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = account.createRecovery(
- email: 'email@example.com',
- url: 'https://example.com',
-);
-
- -
-
Android
-
- 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.createRecovery(
- email = "email@example.com",
- url = "https://example.com"
-)
-
- -
-
Apple
-
- 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 token = try await account.createRecovery(
- email: "email@example.com",
- url: "https://example.com"
-)
-
- -
-
GraphQL
-
- mutation {
- accountCreateRecovery(
- email: "email@example.com",
- url: "https://example.com"
- ) {
- _id
- _createdAt
- userId
- secret
- expire
- }
-}
-
-
-
-
-After receiving a email with the secret attached to the redirect link, submit a request to the Create Password Recovery (confirmation) endpoint to complete the recovery flow. The verification link sent to the user's email address is valid for 1 hour.
-
-
-
--
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.updateRecovery(
- userId: '[USER_ID]',
- secret: '[SECRET]',
- password: 'password'
- passwordAgain: 'password'
-);
-
- -
-
Android
-
- 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 token = account.updateRecovery(
- userId = "[USER_ID]",
- secret = "[SECRET]",
- password = "password",
- passwordAgain = "password"
-)
-
- -
-
Apple
-
- 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 token = try await account.updateRecovery(
- userId: "[USER_ID]",
- secret: "[SECRET]",
- password: "password",
- passwordAgain: "password"
-)
-
- -
-
GraphQL
-
- mutation {
- accountUpdateRecovery(
- userId: "[USER_ID]",
- secret: "[SECRET]",
- password: "password",
- passwordAgain: "password"
- ) {
- _id
- _createdAt
- userId
- secret
- expire
- }
-}
-
-
-
-
-
-User Preferences
-You can store user preferences on a user's account using Appwrite's Update Preferences endpoint. You can store user preferences such as theme, notification settings, or preferred language so they can be synced across multiple devices.
-Preferences are stored as a key-value JSON object. The maximum allowed prefs size is 64kB and throws an error if exceeded.
-
--
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.updatePrefs({darkTheme: true, language: 'en'});
-
-promise.then(function (response) {
- console.log(response);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final user = await account.updatePrefs(
- prefs: {
- "darkTheme": true,
- "language": "en",
- }
-);
-
- -
-
Android
-
- import io.appwrite.Client
-import io.appwrite.services.Account
-
-val client = Client()
- .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
- .setProject("[PROJECT_ID]") // Your project ID
-
-val account = Account(client)
-
-val user = account.updatePrefs(
- prefs = mapOf("darkTheme" to true, "language" to "en")
-)
-
- -
-
Apple
-
- 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 user = try await account.updatePrefs(
- prefs: ["darkTheme": true, "language": "en"]
-)
-
- -
-
GraphQL
-
- mutation {
- accountUpdatePrefs(
- prefs: "{\"darkTheme\": true, \"language\": \"en\"}"
- ) {
- _id
- _createdAt
- _updatedAt
- name
- registration
- status
- passwordUpdate
- email
- phone
- emailVerification
- phoneVerification
- prefs {
- data
- }
- }
-}
-
-
-
-
-After a user's preferences are updated, they can be retrieved using the Get Preferences endpoint.
-
-
--
-
Web
-
- import { Client, Account } from "appwrite";
-
-const client = new Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-const account = new Account(client);
-
-const promise = account.getPrefs();
-
-promise.then(function (prefs) {
- console.log(prefs);
-}, function (error) {
- console.log(error);
-});
-
-
- -
-
Flutter
-
- import 'package:appwrite/appwrite.dart';
-
-final client = Client()
- .setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
- .setProject('[PROJECT_ID]'); // Your project ID
-
-final account = Account(client);
-
-final prefs = await account.getPrefs();
-
- -
-
Android
-
- 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 prefs = account.getPrefs()
-
- -
-
Apple
-
- 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 prefs = try await account.getPrefs()
-
- -
-
GraphQL
-
- query {
- accountGetPrefs {
- data
- }
-}
-
-
-
+
+ Security
+
+
\ No newline at end of file
diff --git a/app/views/docs/getting-started-for-android.phtml b/app/views/docs/getting-started-for-android.phtml
index 74d35cbf0..c410e4caa 100644
--- a/app/views/docs/getting-started-for-android.phtml
+++ b/app/views/docs/getting-started-for-android.phtml
@@ -40,7 +40,7 @@ $androidVersion = (isset($versions['android'])) ? $versions['android'] : '';
OAuth Callback
-In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` 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.
+In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the <application>
tag, along side the existing <activity>
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.
escape('
diff --git a/app/views/docs/getting-started-for-apple.phtml b/app/views/docs/getting-started-for-apple.phtml
index fc6ce3038..2e71911d9 100644
--- a/app/views/docs/getting-started-for-apple.phtml
+++ b/app/views/docs/getting-started-for-apple.phtml
@@ -64,7 +64,7 @@ $appleVersion = $versions['apple'] ?? '';
OAuth Callback
-In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your `Info.plist`
+In order to capture the Appwrite OAuth callback url, the following URL scheme needs to added to your Info.plist
.
escape('CFBundleURLTypes
@@ -83,7 +83,7 @@ $appleVersion = $versions['apple'] ?? '';
');?>
-If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift file to ensure cookies work correctly.
+If you're using UIKit, you'll also need to add a hook to your SceneDelegate.swift
file to ensure cookies work correctly.
escape('
diff --git a/app/views/docs/getting-started-for-web.phtml b/app/views/docs/getting-started-for-web.phtml
index d7ec5bc2a..51d3428df 100644
--- a/app/views/docs/getting-started-for-web.phtml
+++ b/app/views/docs/getting-started-for-web.phtml
@@ -27,7 +27,7 @@ $demos = $platform['demos'] ?? [];
Web platforms allow wildcard hostnames through a * character. The wildcard character can be applied anywhere in a hostname, both *.example.com and prod.*.example.com are valid examples. Avoid using wildcards unless necessary to keep your Appwrite project secure.
-
+
Get Appwrite Web SDK
diff --git a/app/views/docs/index.phtml b/app/views/docs/index.phtml
index 3554cba88..e4f21b661 100644
--- a/app/views/docs/index.phtml
+++ b/app/views/docs/index.phtml
@@ -88,7 +88,13 @@ $cols = [
-
Authentication