diff --git a/.optimize-cache.json b/.optimize-cache.json index 6ef84c3f1a..a8805900cf 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -1438,13 +1438,25 @@ "images/docs/network/pops-map.png": "205ead599703cf47d0df316db8fcc4f48d5eed01508109fc740d17914275e9ab", "images/docs/network/regions-map.png": "c65f1423ab19c3048bf8bf93117e8f2e1d13a2bc705c00307de7ee821e5668a1", "images/docs/platform/add-platform.png": "5a05bb9d75a8d5270bfa5e67df7e6de20a9fad174476a112b5bdab72e7bdad30", - "images/docs/platform/create-api-key.png": "7661b3845e13704643f8ff4f763faa8e61efb90878c3ffa7466ece0910b8ecab", "images/docs/platform/create-webhook.png": "77e08173da6ac534524e025433cf75e532d853a135944a7c6ba2278357d88b2d", "images/docs/platform/dark/add-platform.png": "1bb0e7dba22556e64064951882d625532285fa80bed43fd77774f31545a15b0f", - "images/docs/platform/dark/create-api-key.png": "f15696f0b28dfc46813d7185be11da8be89da72be66b1894cfcc7227036e4afa", "images/docs/platform/dark/create-webhook.png": "88f7f5c857fe986b5803c7df003c4db55faa79e3fa3135cf9491073d0b2736be", "images/docs/platform/dark/execution-details.png": "c0481ddc206447460f9d317ba8d421615066f67a50bc9ef41a8f71766ecffb14", "images/docs/platform/execution-details.png": "ece1364b8b00254bbd982421b6eed6d7f519d34c4e80377fcaaa4cb5d5dd3f89", + "images/docs/project/auth-methods.png": "caa81b517332b06cf539edf25de91a444d8e19ac212d2dd8d75ba14f74933db6", + "images/docs/project/create-api-key.png": "7661b3845e13704643f8ff4f763faa8e61efb90878c3ffa7466ece0910b8ecab", + "images/docs/project/dark/auth-methods.png": "45421e0c586c5f7dc156e823642ab9667f97950f23ca01ce3b8d993ee49fb820", + "images/docs/project/dark/create-api-key.png": "f15696f0b28dfc46813d7185be11da8be89da72be66b1894cfcc7227036e4afa", + "images/docs/project/dark/mock-phones.png": "f26a9cd69f3bc57279cd17109336ea8f55c40f22118b29bd3066afb678ebdf84", + "images/docs/project/dark/platforms.png": "d8e1f107a3c9597ac703fa3c98279bf7bb398761c137455344a8cab05857ec0b", + "images/docs/project/dark/policies.png": "d51a421b4c57b4f2a0d28653e156325b113816a2ad096a2ff15bb15702362b6d", + "images/docs/project/dark/protocols.png": "ff39e7d76dd82d5d13024dd39f589f49ab159c67d1805cb32d3f8ba907b62822", + "images/docs/project/dark/services.png": "fd58dd37313629739db739392a287c5bd15cc196ebb9ed0095b069684aaf6218", + "images/docs/project/mock-phones.png": "ad8c936aafa4782f44611e1c8be9a0a85578485cff3ab49356355f10c178be4a", + "images/docs/project/platforms.png": "7200e9aee04f6fcbc1d232a474b9f80ed406e78ec981c59f69f576649fa8f564", + "images/docs/project/policies.png": "1a35fa9333be000e5131e011fa7e7644aea1148e43d238fa51c98366b7d5871b", + "images/docs/project/protocols.png": "22bfbe1bc2960244c467d8dc373d4b021a79ee9a9b01e9e1d89c5cf3b0bea385", + "images/docs/project/services.png": "b7bb5785e64fdace11e6989a070e326cd1dfc5a67de9a8e17e80ebde20c5fbdf", "images/docs/quick-starts/add-platform.png": "3b13ba983ea1d2529a1f34a719acef903ec0b58879ed511012280a28ccbde17e", "images/docs/quick-starts/create-project.png": "7fdb25def02c5dbdb08cd38c2d03b7b454c930194a900553e3e68d51cb28a1d5", "images/docs/quick-starts/dark/add-platform.png": "b12a85b64b136589268831b9cb26a664ec97418ad25a38be5273baab8253aa16", diff --git a/mock-phones-dark.png b/mock-phones-dark.png new file mode 100644 index 0000000000..150857f110 Binary files /dev/null and b/mock-phones-dark.png differ diff --git a/src/redirects.json b/src/redirects.json index b763ed84e7..a315ad8533 100644 --- a/src/redirects.json +++ b/src/redirects.json @@ -1,4 +1,8 @@ [ + { + "link": "/docs/advanced/platform/api-keys", + "redirect": "/docs/products/project/api-keys" + }, { "link": "/docs/getting-started-for-web", "redirect": "/docs/quick-starts" @@ -201,7 +205,7 @@ }, { "link": "/docs/keys", - "redirect": "/docs/advanced/platform/api-keys" + "redirect": "/docs/products/project/api-keys" }, { "link": "/docs/permissions", diff --git a/src/routes/docs/Sidebar.svelte b/src/routes/docs/Sidebar.svelte index 6a66ce9388..4ce7da6fbb 100644 --- a/src/routes/docs/Sidebar.svelte +++ b/src/routes/docs/Sidebar.svelte @@ -84,6 +84,12 @@ icon: 'icon-globe-alt', isParent: true, new: isNewUntil('19 Jul 2025') + }, + { + label: 'Project', + href: '/docs/products/project', + icon: 'icon-briefcase', + isParent: true } ] }, diff --git a/src/routes/docs/advanced/platform/+layout.svelte b/src/routes/docs/advanced/platform/+layout.svelte index 5e1739b622..00fdefe579 100644 --- a/src/routes/docs/advanced/platform/+layout.svelte +++ b/src/routes/docs/advanced/platform/+layout.svelte @@ -59,10 +59,6 @@ label: 'Rate limits', href: '/docs/advanced/platform/rate-limits' }, - { - label: 'API keys', - href: '/docs/advanced/platform/api-keys' - }, { label: 'Dev keys', href: '/docs/advanced/platform/dev-keys' diff --git a/src/routes/docs/advanced/platform/+page.markdoc b/src/routes/docs/advanced/platform/+page.markdoc index d85400548e..d87454b7ec 100644 --- a/src/routes/docs/advanced/platform/+page.markdoc +++ b/src/routes/docs/advanced/platform/+page.markdoc @@ -46,10 +46,6 @@ Control which users can access which resources. Appwrite has rate limits on some endpoints to prevent abuse. {% /cards_item %} -{% cards_item href="/docs/advanced/platform/api-keys" title="API keys" %} -Create and manage API keys used by Server SDKs. -{% /cards_item %} - {% cards_item href="/docs/advanced/platform/dev-keys" title="Dev keys" %} Create and manage dev keys used by Client SDKs in dev environments. {% /cards_item %} diff --git a/src/routes/docs/products/project/+layout.svelte b/src/routes/docs/products/project/+layout.svelte new file mode 100644 index 0000000000..515d45ea3a --- /dev/null +++ b/src/routes/docs/products/project/+layout.svelte @@ -0,0 +1,59 @@ + + + + + + diff --git a/src/routes/docs/products/project/+page.markdoc b/src/routes/docs/products/project/+page.markdoc new file mode 100644 index 0000000000..0dddf4678b --- /dev/null +++ b/src/routes/docs/products/project/+page.markdoc @@ -0,0 +1,34 @@ +--- +layout: article +title: Project +description: Configure your Appwrite project, including auth methods, platforms, protocols, services, and policies. +back: /docs +--- + +An Appwrite **Project** is the top-level container for all the resources your app uses, from users and databases to storage buckets and functions. The settings on a project control which authentication methods are available, which client platforms can connect, which protocols and services are exposed, and which policies apply to the resources inside it. + +# Concepts {% #concepts %} + +{% cards %} +{% cards_item href="/docs/products/project/auth-methods" title="Auth methods" %} +Enable or disable authentication methods on your project. +{% /cards_item %} +{% cards_item href="/docs/products/project/api-keys" title="API keys" %} +Create and manage API keys used by Server SDKs. +{% /cards_item %} +{% cards_item href="/docs/products/project/platforms" title="Platforms" %} +Register the apps and origins that are allowed to call your project. +{% /cards_item %} +{% cards_item href="/docs/products/project/protocols" title="Protocols" %} +Toggle the API protocols clients can use to reach your project. +{% /cards_item %} +{% cards_item href="/docs/products/project/services" title="Services" %} +Turn individual Appwrite services on or off for your project. +{% /cards_item %} +{% cards_item href="/docs/products/project/policies" title="Policies" %} +Configure project-wide policies that apply across resources. +{% /cards_item %} +{% cards_item href="/docs/products/project/mock-phones" title="Mock phones" %} +Register fictional phone numbers and OTPs to test phone authentication. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/advanced/platform/api-keys/+page.markdoc b/src/routes/docs/products/project/api-keys/+page.markdoc similarity index 99% rename from src/routes/docs/advanced/platform/api-keys/+page.markdoc rename to src/routes/docs/products/project/api-keys/+page.markdoc index 99671a0e5c..23568260e2 100644 --- a/src/routes/docs/advanced/platform/api-keys/+page.markdoc +++ b/src/routes/docs/products/project/api-keys/+page.markdoc @@ -23,10 +23,10 @@ API keys are for server SDKs and the CLI in production environments, while Dev k # Create API key {% #create-api-key %} {% only_dark %} -![Project settings screen](/images/docs/platform/dark/create-api-key.png) +![Project settings screen](/images/docs/project/dark/create-api-key.png) {% /only_dark %} {% only_light %} -![Project settings screen](/images/docs/platform/create-api-key.png) +![Project settings screen](/images/docs/project/create-api-key.png) {% /only_light %} To create a new API key, navigate to **Overview** > **Integration** > **API keys** and click **Create API key**. diff --git a/src/routes/docs/products/project/auth-methods/+page.markdoc b/src/routes/docs/products/project/auth-methods/+page.markdoc new file mode 100644 index 0000000000..702743f0fd --- /dev/null +++ b/src/routes/docs/products/project/auth-methods/+page.markdoc @@ -0,0 +1,287 @@ +--- +layout: article +title: Auth methods +description: Enable or disable authentication methods on your Appwrite project programmatically using server SDKs. +--- + +Each Appwrite project ships with a configurable set of authentication methods, including email and password, magic URL, email OTP, phone, anonymous sessions, JWT, and team invites. Methods can be toggled on or off from the Appwrite Console under **Auth** > **Settings**, or programmatically through any server SDK using the Project service. + +When a method is disabled, the matching account endpoints reject requests for that project until it is re-enabled. + +# Toggle from the Console {% #toggle-console %} + +{% only_dark %} +![Auth methods settings in the Appwrite Console](/images/docs/project/dark/auth-methods.png) +{% /only_dark %} +{% only_light %} +![Auth methods settings in the Appwrite Console](/images/docs/project/auth-methods.png) +{% /only_light %} + +To toggle auth methods manually: + +1. Open your project in the Appwrite Console. +2. Navigate to **Auth** in the sidebar, then open the **Settings** tab. +3. In the **Auth methods** card, toggle individual methods on or off, or use **Enable all** or **Disable all** for bulk changes. +4. Changes take effect immediately. No deploy or restart is required. + +OAuth2 providers are configured separately in the **OAuth2 Providers** section on the same page. + +# Method IDs {% #method-ids %} + +The `methodId` parameter accepts one of the following values: + +| Method ID | Description | +| --- | --- | +| `email-password` | Email and password sign-up and login. | +| `magic-url` | Passwordless login using a magic link sent to the user's email. | +| `email-otp` | Time-based one-time password sent to the user's email. | +| `phone` | SMS-based phone authentication. | +| `anonymous` | Guest sessions for unauthenticated visitors. | +| `invites` | Team invitations for collaborative access. | +| `jwt` | JWT-based authentication for delegated access. | + +# Enable or disable a method {% #update-auth-method %} + +Use the Project service `updateAuthMethod` endpoint with a method ID and the `enabled` flag. + +{% info title="Required scope" %} +The API key used for these calls needs the `project.write` scope. +{% /info %} + +{% multicode %} +```server-nodejs +import { Client, Project, AuthMethod } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateAuthMethod({ + methodId: AuthMethod.EmailPassword, + enabled: false +}); +``` +```server-deno +import { Client, Project, AuthMethod } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateAuthMethod({ + methodId: AuthMethod.EmailPassword, + enabled: false +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateAuthMethod( + methodId: AuthMethod::EMAILPASSWORD(), + enabled: false +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project +from appwrite.enums import AuthMethod + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_auth_method( + method_id = AuthMethod.EMAIL_PASSWORD, + enabled = False +) +``` +```server-ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_auth_method( + method_id: AuthMethod::EMAIL_PASSWORD, + enabled: false +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Enums; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateAuthMethod( + methodId: AuthMethod.EmailPassword, + enabled: false +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart' as enums; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateAuthMethod( + methodId: enums.AuthMethod.emailPassword, + enabled: false, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project +import io.appwrite.enums.AuthMethod + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val result = project.updateAuthMethod( + methodId = AuthMethod.EMAIL_PASSWORD, + enabled = false +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; +import io.appwrite.enums.AuthMethod; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateAuthMethod( + AuthMethod.EMAIL_PASSWORD, // methodId + false, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateAuthMethod( + methodId: .emailPassword, + enabled: false +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.UpdateAuthMethod( + "email-password", + false, + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; +use appwrite::enums::AuthMethod; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_auth_method( + AuthMethod::EmailPassword, + false, + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-auth-method \ + --method-id email-password \ + --enabled false +``` +{% /multicode %} + +The endpoint returns the updated [Project](/docs/references/cloud/models/project) document with the new method state applied. diff --git a/src/routes/docs/products/project/mock-phones/+page.markdoc b/src/routes/docs/products/project/mock-phones/+page.markdoc new file mode 100644 index 0000000000..9488a09bcf --- /dev/null +++ b/src/routes/docs/products/project/mock-phones/+page.markdoc @@ -0,0 +1,1100 @@ +--- +layout: article +title: Mock phones +description: Register fictional phone numbers and OTPs to test phone authentication flows without sending real SMS messages. +--- + +Mock phones let you register fictional phone numbers and a fixed verification code at the project level. When a tester signs in with a registered number, the registered code works in place of a real SMS, so phone authentication flows can be exercised in CI, demo accounts, and app store review submissions without sending SMS or paying provider fees. + +Each project stores its mock phones on the project document. Numbers must be in [E.164](https://en.wikipedia.org/wiki/E.164) format, and verification codes are exactly six digits. + +# Add from the Console {% #toggle-console %} + +{% only_dark %} +![Mock phone numbers settings in the Appwrite Console](/images/docs/project/dark/mock-phones.png) +{% /only_dark %} +{% only_light %} +![Mock phone numbers settings in the Appwrite Console](/images/docs/project/mock-phones.png) +{% /only_light %} + +To add a mock phone manually: + +1. Open your project in the Appwrite Console. +2. Navigate to **Auth** in the sidebar, then open the **Settings** tab. +3. Scroll to the **Mock phone numbers** card and click **Add a number**. +4. Enter a phone number in E.164 format (for example, `+15555550100`) and a six-digit verification code. +5. Click **Save** on the row, then **Update** at the bottom of the section to persist. + +Use fictional ranges (such as North American `555` numbers) to avoid collision with real subscribers. + +# Manage with a Server SDK {% #manage-with-sdk %} + +The Project service exposes endpoints to list, create, get, update, and delete mock phones. All endpoints require an API key with the appropriate scope or a Console session. + +{% info title="Required scopes" %} +Reading mock phones requires the `mocks.read` scope. Creating, updating, or deleting requires `mocks.write`. +{% /info %} + +## Create a mock phone {% #create-mock-phone %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.createMockPhone({ + number: '+15555550100', + otp: '123456' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.createMockPhone({ + number: '+15555550100', + otp: '123456' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->createMockPhone( + number: '+15555550100', + otp: '123456' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.create_mock_phone( + number = '+15555550100', + otp = '123456' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +result = project.create_mock_phone( + number: '+15555550100', + otp: '123456' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.CreateMockPhone( + number: "+15555550100", + otp: "123456" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.createMockPhone( + number: '+15555550100', + otp: '123456', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val result = project.createMockPhone( + number = "+15555550100", + otp = "123456" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.createMockPhone( + "+15555550100", // number + "123456", // otp + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.createMockPhone( + number: "+15555550100", + otp: "123456" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.CreateMockPhone( + "+15555550100", + "123456", + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.create_mock_phone( + "+15555550100", + "123456", + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project create-mock-phone \ + --number +15555550100 \ + --otp 123456 +``` +{% /multicode %} + +The endpoint returns the new [MockNumber](/docs/references/cloud/models/mockNumber) document. + +## List mock phones {% #list-mock-phones %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.listMockPhones(); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.listMockPhones(); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->listMockPhones(); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.list_mock_phones() +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +result = project.list_mock_phones() +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.ListMockPhones(); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.listMockPhones(); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val result = project.listMockPhones() +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.listMockPhones(new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); +})); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.listMockPhones() +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.ListMockPhones() + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.list_mock_phones(None, None).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project list-mock-phones \ + --limit 25 +``` +{% /multicode %} + +## Get a mock phone {% #get-mock-phone %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.getMockPhone({ + number: '+15555550100' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.getMockPhone({ + number: '+15555550100' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->getMockPhone( + number: '+15555550100' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.get_mock_phone( + number = '+15555550100' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +result = project.get_mock_phone( + number: '+15555550100' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.GetMockPhone( + number: "+15555550100" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.getMockPhone( + number: '+15555550100', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val result = project.getMockPhone( + number = "+15555550100" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.getMockPhone( + "+15555550100", // number + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.getMockPhone( + number: "+15555550100" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.GetMockPhone("+15555550100") + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.get_mock_phone("+15555550100").await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project get-mock-phone --number +15555550100 +``` +{% /multicode %} + +## Update a mock phone {% #update-mock-phone %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateMockPhone({ + number: '+15555550100', + otp: '654321' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateMockPhone({ + number: '+15555550100', + otp: '654321' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateMockPhone( + number: '+15555550100', + otp: '654321' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_mock_phone( + number = '+15555550100', + otp = '654321' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +result = project.update_mock_phone( + number: '+15555550100', + otp: '654321' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateMockPhone( + number: "+15555550100", + otp: "654321" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateMockPhone( + number: '+15555550100', + otp: '654321', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val result = project.updateMockPhone( + number = "+15555550100", + otp = "654321" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateMockPhone( + "+15555550100", // number + "654321", // otp + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateMockPhone( + number: "+15555550100", + otp: "654321" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.UpdateMockPhone("+15555550100", "654321") + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_mock_phone("+15555550100", "654321").await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-mock-phone \ + --number +15555550100 \ + --otp 654321 +``` +{% /multicode %} + +## Delete a mock phone {% #delete-mock-phone %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +await project.deleteMockPhone({ + number: '+15555550100' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +await project.deleteMockPhone({ + number: '+15555550100' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$project->deleteMockPhone( + number: '+15555550100' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +project.delete_mock_phone( + number = '+15555550100' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +project.delete_mock_phone( + number: '+15555550100' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +await project.DeleteMockPhone( + number: "+15555550100" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +await project.deleteMockPhone( + number: '+15555550100', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +project.deleteMockPhone( + number = "+15555550100" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.deleteMockPhone( + "+15555550100", // number + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +try await project.deleteMockPhone( + number: "+15555550100" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + _, err := project.DeleteMockPhone("+15555550100") + + if err != nil { + panic(err) + } + + fmt.Println("deleted") +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + project.delete_mock_phone("+15555550100").await?; + + Ok(()) +} +``` +```bash +appwrite project delete-mock-phone --number +15555550100 +``` +{% /multicode %} + +# Errors {% #errors %} + +| Code | Type | Description | +| --- | --- | --- | +| 404 | `mock_number_not_found` | No mock phone exists for the supplied number. | +| 409 | `mock_number_already_exists` | A mock phone with the same number is already registered. | +| 400 | `mock_number_limit_exceeded` | The project has reached the maximum number of mock phones. | diff --git a/src/routes/docs/products/project/platforms/+page.markdoc b/src/routes/docs/products/project/platforms/+page.markdoc new file mode 100644 index 0000000000..98bebe3b27 --- /dev/null +++ b/src/routes/docs/products/project/platforms/+page.markdoc @@ -0,0 +1,988 @@ +--- +layout: article +title: Platforms +description: Register Web, Apple, Android, Windows, and Linux apps to your Appwrite project programmatically using server SDKs. +--- + +Each Appwrite project has a list of registered platforms. A platform identifies a client application that is allowed to talk to your project's API: a Web platform pins an allowed hostname for CORS, while Apple, Android, Windows, and Linux platforms pin a bundle, package, or application ID for native clients. + +Platforms can be added from the Appwrite Console, or programmatically through any server SDK using the Project service. + +# Manage from the Console {% #manage-console %} + +{% only_dark %} +![Project platforms in the Appwrite Console](/images/docs/project/dark/platforms.png) +{% /only_dark %} +{% only_light %} +![Project platforms in the Appwrite Console](/images/docs/project/platforms.png) +{% /only_light %} + +To add a platform manually: + +1. Open your project in the Appwrite Console. +2. On the project **Overview**, scroll to the **Integrations** card and select the **Platforms** tab. +3. Click **Add platform** and choose the platform type (Web, Flutter, Android, Apple, or React Native). +4. Fill in the name and the platform's identifier (hostname for Web, bundle or package ID for native), then click **Create platform**. +5. To rename or remove a platform later, click its row and use the edit dialog or the **Delete** button. + +# Platform types {% #platform-types %} + +The Project service exposes a dedicated create method per platform type. Each method takes a unique `platformId`, a display `name`, and the platform's identifier: + +| Type | Method | Identifier param | +| --- | --- | --- | +| Web | `createWebPlatform` | `hostname` (e.g. `app.example.com`) | +| Apple | `createApplePlatform` | `bundleIdentifier` (e.g. `com.example.app`) | +| Android | `createAndroidPlatform` | `applicationId` (e.g. `com.example.app`) | +| Windows | `createWindowsPlatform` | `packageIdentifierName` | +| Linux | `createLinuxPlatform` | `packageName` | + +Flutter and React Native platforms shown in the Console map to the underlying Apple, Android, or Web type based on the target you pick. + +# Register a platform {% #register-platform %} + +The example below registers a Web platform. Swap the method name and identifier param to register Apple, Android, Windows, or Linux platforms. + +{% info title="Required scopes" %} +The API key used for these calls needs `platforms.write` to create, update, or delete platforms, and `platforms.read` to list or fetch them. +{% /info %} + +{% multicode %} +```server-nodejs +import { Client, Project, ID } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.createWebPlatform({ + platformId: ID.unique(), + name: 'My Web App', + hostname: 'app.example.com' +}); +``` +```server-deno +import { Client, Project, ID } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.createWebPlatform({ + platformId: ID.unique(), + name: 'My Web App', + hostname: 'app.example.com' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->createWebPlatform( + platformId: ID::unique(), + name: 'My Web App', + hostname: 'app.example.com' +); +``` +```server-python +from appwrite.client import Client +from appwrite.id import ID +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.create_web_platform( + platform_id = ID.unique(), + name = 'My Web App', + hostname = 'app.example.com' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.create_web_platform( + platform_id: ID.unique(), + name: 'My Web App', + hostname: 'app.example.com' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.CreateWebPlatform( + platformId: ID.Unique(), + name: "My Web App", + hostname: "app.example.com" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.createWebPlatform( + platformId: ID.unique(), + name: 'My Web App', + hostname: 'app.example.com', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.createWebPlatform( + platformId = ID.unique(), + name = "My Web App", + hostname = "app.example.com" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.createWebPlatform( + ID.unique(), // platformId + "My Web App", // name + "app.example.com", // hostname + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.createWebPlatform( + platformId: ID.unique(), + name: "My Web App", + hostname: "app.example.com" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/id" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + project := appwrite.NewProject(client) + result, err := project.CreateWebPlatform( + id.Unique(), + "My Web App", + "app.example.com", + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::id::ID; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.create_web_platform( + ID::unique(), + "My Web App", + "app.example.com", + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project create-web-platform \ + --platform-id 'unique()' \ + --name "My Web App" \ + --hostname app.example.com +``` +{% /multicode %} + +# List platforms {% #list-platforms %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.listPlatforms({ + queries: [], + total: false +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.listPlatforms({ + queries: [], + total: false +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->listPlatforms( + queries: [], + total: false +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.list_platforms( + queries = [], + total = False +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.list_platforms( + queries: [], + total: false +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.ListPlatforms( + queries: new List(), + total: false +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.listPlatforms( + queries: [], + total: false, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.listPlatforms( + queries = listOf(), + total = false +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.listPlatforms( + List.of(), // queries + false, // total + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.listPlatforms( + queries: [], + total: false +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/project" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.ListPlatforms( + project.WithListPlatformsQueries([]interface{}{}), + project.WithListPlatformsTotal(false), + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.list_platforms( + Some(vec![]), + Some(false), + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project list-platforms \ + --limit 25 +``` +{% /multicode %} + +# Update a platform {% #update-platform %} + +Each platform type has a matching update method (`updateWebPlatform`, `updateApplePlatform`, and so on). The example below updates a Web platform's name and hostname. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateWebPlatform({ + platformId: '', + name: 'Renamed Web App', + hostname: 'app.example.com' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateWebPlatform({ + platformId: '', + name: 'Renamed Web App', + hostname: 'app.example.com' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateWebPlatform( + platformId: '', + name: 'Renamed Web App', + hostname: 'app.example.com' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_web_platform( + platform_id = '', + name = 'Renamed Web App', + hostname = 'app.example.com' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_web_platform( + platform_id: '', + name: 'Renamed Web App', + hostname: 'app.example.com' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateWebPlatform( + platformId: "", + name: "Renamed Web App", + hostname: "app.example.com" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateWebPlatform( + platformId: '', + name: 'Renamed Web App', + hostname: 'app.example.com', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateWebPlatform( + platformId = "", + name = "Renamed Web App", + hostname = "app.example.com" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateWebPlatform( + "", // platformId + "Renamed Web App", // name + "app.example.com", // hostname + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateWebPlatform( + platformId: "", + name: "Renamed Web App", + hostname: "app.example.com" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateWebPlatform( + "", + "Renamed Web App", + "app.example.com", + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_web_platform( + "", + "Renamed Web App", + "app.example.com", + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-web-platform \ + --platform-id \ + --name "Renamed Web App" \ + --hostname app.example.com +``` +{% /multicode %} + +# Delete a platform {% #delete-platform %} + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +await project.deletePlatform({ + platformId: '' +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +await project.deletePlatform({ + platformId: '' +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$project->deletePlatform( + platformId: '' +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +project.delete_platform( + platform_id = '' +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +project.delete_platform( + platform_id: '' +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +await project.DeletePlatform( + platformId: "" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +await project.deletePlatform( + platformId: '', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +project.deletePlatform( + platformId = "" +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.deletePlatform( + "", // platformId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +try await project.deletePlatform( + platformId: "" +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.DeletePlatform( + "", + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + project.delete_platform( + "", + ).await?; + + Ok(()) +} +``` +```bash +appwrite project delete-platform \ + --platform-id +``` +{% /multicode %} + +# Benefits {% #benefits %} + +- **Repeatable provisioning.** Script the full set of platforms a project needs and recreate it on demand, without clicking through the Console. +- **Environment parity.** Keep dev, staging, and production projects in sync by running the same script against each one. +- **CI and automation.** Add or rotate platforms from a CI job when a new preview environment spins up or a domain changes. diff --git a/src/routes/docs/products/project/policies/+page.markdoc b/src/routes/docs/products/project/policies/+page.markdoc new file mode 100644 index 0000000000..a25f92a13e --- /dev/null +++ b/src/routes/docs/products/project/policies/+page.markdoc @@ -0,0 +1,2032 @@ +--- +layout: article +title: Policies +description: Configure password rules, session limits, user limits, and membership privacy on your Appwrite project programmatically using server SDKs. +--- + +Project policies control how users authenticate, how long their sessions live, how many users can sign up, and what team members can see about each other. Each policy is an independent toggle on the project. + +Policies can be configured from the Appwrite Console, or programmatically through any server SDK using the Project service. + +# Manage from the Console {% #manage-console %} + +{% only_dark %} +![Project policies in the Appwrite Console](/images/docs/project/dark/policies.png) +{% /only_dark %} +{% only_light %} +![Project policies in the Appwrite Console](/images/docs/project/policies.png) +{% /only_light %} + +To configure policies manually: + +1. Open your project in the Appwrite Console. +2. Navigate to **Auth** in the sidebar. +3. Open the **Security** tab. +4. Adjust the policy you want, then click **Update** on its card. + +# Available policies {% #available-policies %} + +| Policy ID | SDK method | Body | +| --- | --- | --- | +| `password-dictionary` | `updatePasswordDictionaryPolicy` | `enabled` | +| `password-history` | `updatePasswordHistoryPolicy` | `total` (1–`APP_LIMIT_COUNT`, or `null`) | +| `password-personal-data` | `updatePasswordPersonalDataPolicy` | `enabled` | +| `session-alert` | `updateSessionAlertPolicy` | `enabled` | +| `session-duration` | `updateSessionDurationPolicy` | `duration` (5–31536000 seconds) | +| `session-invalidation` | `updateSessionInvalidationPolicy` | `enabled` | +| `session-limit` | `updateSessionLimitPolicy` | `total` (1–`APP_LIMIT_COUNT`, or `null`) | +| `user-limit` | `updateUserLimitPolicy` | `total` (1–`APP_LIMIT_COUNT`, or `null`) | +| `membership-privacy` | `updateMembershipPrivacyPolicy` | `userId`, `userEmail`, `userPhone`, `userName`, `userMFA` (all bool, all optional) | + +{% info title="Required scopes" %} +The API key used for these calls needs `policies.read` to list or fetch policies, and `policies.write` to update them. +{% /info %} + +# Update password dictionary policy {% #update-password-dictionary-policy %} + +When enabled, new passwords are checked against a dictionary of common passwords and rejected if they match. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordDictionaryPolicy({ + enabled: true +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordDictionaryPolicy({ + enabled: true +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updatePasswordDictionaryPolicy( + enabled: true +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_password_dictionary_policy( + enabled = True +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_password_dictionary_policy( + enabled: true +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdatePasswordDictionaryPolicy( + enabled: true +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updatePasswordDictionaryPolicy( + enabled: true, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updatePasswordDictionaryPolicy( + enabled = true +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updatePasswordDictionaryPolicy( + true, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updatePasswordDictionaryPolicy( + enabled: true +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdatePasswordDictionaryPolicy(true) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_password_dictionary_policy(true).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-password-dictionary-policy \ + --enabled true +``` +{% /multicode %} + +# Update password history policy {% #update-password-history-policy %} + +Stores the last `total` password hashes per user and rejects new passwords that match. Pass `null` to disable. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordHistoryPolicy({ + total: 5 +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordHistoryPolicy({ + total: 5 +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updatePasswordHistoryPolicy( + total: 5 +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_password_history_policy( + total = 5 +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_password_history_policy( + total: 5 +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdatePasswordHistoryPolicy( + total: 5 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updatePasswordHistoryPolicy( + total: 5, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updatePasswordHistoryPolicy( + total = 5 +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updatePasswordHistoryPolicy( + 5, // total + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updatePasswordHistoryPolicy( + total: 5 +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdatePasswordHistoryPolicy(5) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_password_history_policy(5).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-password-history-policy \ + --total 5 +``` +{% /multicode %} + +# Update password personal data policy {% #update-password-personal-data-policy %} + +When enabled, new passwords are rejected if they contain the user's ID, name, email, or phone number. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordPersonalDataPolicy({ + enabled: true +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updatePasswordPersonalDataPolicy({ + enabled: true +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updatePasswordPersonalDataPolicy( + enabled: true +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_password_personal_data_policy( + enabled = True +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_password_personal_data_policy( + enabled: true +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdatePasswordPersonalDataPolicy( + enabled: true +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updatePasswordPersonalDataPolicy( + enabled: true, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updatePasswordPersonalDataPolicy( + enabled = true +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updatePasswordPersonalDataPolicy( + true, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updatePasswordPersonalDataPolicy( + enabled: true +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdatePasswordPersonalDataPolicy(true) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_password_personal_data_policy(true).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-password-personal-data-policy \ + --enabled true +``` +{% /multicode %} + +# Update session alert policy {% #update-session-alert-policy %} + +When enabled, the user receives an email each time a new session is created. The first session after sign-up does not trigger an alert. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionAlertPolicy({ + enabled: true +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionAlertPolicy({ + enabled: true +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateSessionAlertPolicy( + enabled: true +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_session_alert_policy( + enabled = True +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_session_alert_policy( + enabled: true +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateSessionAlertPolicy( + enabled: true +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateSessionAlertPolicy( + enabled: true, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateSessionAlertPolicy( + enabled = true +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateSessionAlertPolicy( + true, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateSessionAlertPolicy( + enabled: true +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateSessionAlertPolicy(true) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_session_alert_policy(true).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-session-alert-policy \ + --enabled true +``` +{% /multicode %} + +# Update session duration policy {% #update-session-duration-policy %} + +Sets the maximum lifetime of a session in seconds. Valid range is 5 seconds to 31536000 seconds (one year). + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionDurationPolicy({ + duration: 86400 +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionDurationPolicy({ + duration: 86400 +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateSessionDurationPolicy( + duration: 86400 +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_session_duration_policy( + duration = 86400 +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_session_duration_policy( + duration: 86400 +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateSessionDurationPolicy( + duration: 86400 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateSessionDurationPolicy( + duration: 86400, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateSessionDurationPolicy( + duration = 86400 +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateSessionDurationPolicy( + 86400, // duration + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateSessionDurationPolicy( + duration: 86400 +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateSessionDurationPolicy(86400) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_session_duration_policy(86400).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-session-duration-policy \ + --duration 86400 +``` +{% /multicode %} + +# Update session invalidation policy {% #update-session-invalidation-policy %} + +When enabled, all existing sessions for a user are invalidated when their password is changed. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionInvalidationPolicy({ + enabled: true +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionInvalidationPolicy({ + enabled: true +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateSessionInvalidationPolicy( + enabled: true +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_session_invalidation_policy( + enabled = True +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_session_invalidation_policy( + enabled: true +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateSessionInvalidationPolicy( + enabled: true +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateSessionInvalidationPolicy( + enabled: true, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateSessionInvalidationPolicy( + enabled = true +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateSessionInvalidationPolicy( + true, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateSessionInvalidationPolicy( + enabled: true +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateSessionInvalidationPolicy(true) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_session_invalidation_policy(true).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-session-invalidation-policy \ + --enabled true +``` +{% /multicode %} + +# Update session limit policy {% #update-session-limit-policy %} + +Sets the maximum number of concurrent sessions allowed per user. When the limit is reached, the oldest session is dropped to make room for a new one. Pass `null` to remove the limit. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionLimitPolicy({ + total: 10 +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateSessionLimitPolicy({ + total: 10 +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateSessionLimitPolicy( + total: 10 +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_session_limit_policy( + total = 10 +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_session_limit_policy( + total: 10 +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateSessionLimitPolicy( + total: 10 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateSessionLimitPolicy( + total: 10, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateSessionLimitPolicy( + total = 10 +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateSessionLimitPolicy( + 10, // total + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateSessionLimitPolicy( + total: 10 +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateSessionLimitPolicy(10) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_session_limit_policy(10).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-session-limit-policy \ + --total 10 +``` +{% /multicode %} + +# Update user limit policy {% #update-user-limit-policy %} + +Sets the maximum number of users in the project. Existing users remain active when the limit is reached or exceeded; new sign-ups are rejected. Pass `null` to remove the limit. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateUserLimitPolicy({ + total: 1000 +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateUserLimitPolicy({ + total: 1000 +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateUserLimitPolicy( + total: 1000 +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_user_limit_policy( + total = 1000 +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_user_limit_policy( + total: 1000 +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateUserLimitPolicy( + total: 1000 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateUserLimitPolicy( + total: 1000, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateUserLimitPolicy( + total = 1000 +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateUserLimitPolicy( + 1000, // total + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateUserLimitPolicy( + total: 1000 +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateUserLimitPolicy(1000) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_user_limit_policy(1000).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-user-limit-policy \ + --total 1000 +``` +{% /multicode %} + +# Update membership privacy policy {% #update-membership-privacy-policy %} + +Controls which fields of one team member's profile are visible to other members in the same team. Each field can be toggled independently. + +{% multicode %} +```server-nodejs +import { Client, Project } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateMembershipPrivacyPolicy({ + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false +}); +``` +```server-deno +import { Client, Project } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateMembershipPrivacyPolicy({ + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateMembershipPrivacyPolicy( + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_membership_privacy_policy( + user_id = True, + user_email = False, + user_phone = False, + user_name = True, + user_mfa = False +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_membership_privacy_policy( + user_id: true, + user_email: false, + user_phone: false, + user_name: true, + user_mfa: false +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateMembershipPrivacyPolicy( + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateMembershipPrivacyPolicy( + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateMembershipPrivacyPolicy( + userId = true, + userEmail = false, + userPhone = false, + userName = true, + userMFA = false +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateMembershipPrivacyPolicy( + true, // userId + false, // userEmail + false, // userPhone + true, // userName + false, // userMFA + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateMembershipPrivacyPolicy( + userId: true, + userEmail: false, + userPhone: false, + userName: true, + userMFA: false +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/project" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateMembershipPrivacyPolicy( + project.WithUpdateMembershipPrivacyPolicyUserId(true), + project.WithUpdateMembershipPrivacyPolicyUserEmail(false), + project.WithUpdateMembershipPrivacyPolicyUserPhone(false), + project.WithUpdateMembershipPrivacyPolicyUserName(true), + project.WithUpdateMembershipPrivacyPolicyUserMFA(false), + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_membership_privacy_policy( + Some(true), + Some(false), + Some(false), + Some(true), + Some(false), + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-membership-privacy-policy \ + --user-id true \ + --user-email false \ + --user-phone false \ + --user-name true \ + --user-mfa false +``` +{% /multicode %} + +# Benefits {% #benefits %} + +- **Codify auth posture.** Keep password rules, session lifetimes, and user caps in version control alongside the rest of your project configuration. +- **Environment parity.** Apply the same policy script to dev, staging, and production projects to keep them aligned. +- **Faster incident response.** When a policy needs to change in a hurry (e.g. tightening session duration after a breach), update it from a script instead of clicking through the Console. diff --git a/src/routes/docs/products/project/protocols/+page.markdoc b/src/routes/docs/products/project/protocols/+page.markdoc new file mode 100644 index 0000000000..9c7e778a44 --- /dev/null +++ b/src/routes/docs/products/project/protocols/+page.markdoc @@ -0,0 +1,285 @@ +--- +layout: article +title: Protocols +description: Enable or disable the REST, GraphQL, and WebSocket protocols on your Appwrite project programmatically using server SDKs. +--- + +Each Appwrite project exposes its API through three protocols: REST, GraphQL, and WebSocket. You can disable any protocol your clients don't use to shrink the project's surface area, then re-enable it when needed. + +Protocols can be toggled from the Appwrite Console, or programmatically through any server SDK using the Project service. + +# Manage from the Console {% #manage-console %} + +{% only_dark %} +![Project protocols in the Appwrite Console](/images/docs/project/dark/protocols.png) +{% /only_dark %} +{% only_light %} +![Project protocols in the Appwrite Console](/images/docs/project/protocols.png) +{% /only_light %} + +To toggle a protocol manually: + +1. Open your project in the Appwrite Console. +2. Open **Settings** from the bottom of the side nav. +3. Scroll to the **Protocols** card. +4. Flip the switch next to REST, GraphQL, or WebSocket. Use **Disable all** to turn off every protocol at once. + +# Available protocols {% #available-protocols %} + +| Protocol ID | Description | +| --- | --- | +| `rest` | Standard HTTP API requests from client SDKs. | +| `graphql` | GraphQL API access for queries and mutations. | +| `websocket` | Realtime subscriptions over WebSocket connections. | + +# Update a protocol {% #update-protocol %} + +The example below disables the REST protocol. Pass `enabled: true` to re-enable it. + +Disabling REST blocks client SDK traffic only. Server SDKs using an API key keep access, so you can always call this endpoint again to re-enable the protocol. + +{% info title="Required scope" %} +The API key used for this call needs the `project.write` scope. +{% /info %} + +{% multicode %} +```server-nodejs +import { Client, Project, ProtocolId } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateProtocol({ + protocolId: ProtocolId.Rest, + enabled: false +}); +``` +```server-deno +import { Client, Project, ProtocolId } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateProtocol({ + protocolId: ProtocolId.Rest, + enabled: false +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateProtocol( + protocolId: ProtocolId::REST(), + enabled: false +); +``` +```server-python +from appwrite.client import Client +from appwrite.enums import ProtocolId +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_protocol( + protocol_id = ProtocolId.REST, + enabled = False +) +``` +```server-ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_protocol( + protocol_id: ProtocolId::REST, + enabled: false +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Enums; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateProtocol( + protocolId: ProtocolId.Rest, + enabled: false +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart' as enums; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateProtocol( + protocolId: enums.ProtocolId.rest, + enabled: false, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.enums.ProtocolId +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateProtocol( + protocolId = ProtocolId.REST, + enabled = false +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.enums.ProtocolId; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateProtocol( + ProtocolId.REST, // protocolId + false, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateProtocol( + protocolId: .rest, + enabled: false +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateProtocol( + "rest", + false, + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::enums::ProtocolId; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_protocol( + ProtocolId::Rest, + false, + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-protocol \ + --protocol-id rest \ + --enabled false +``` +{% /multicode %} + +# Benefits {% #benefits %} + +- **Shrink the client surface area.** Disabled protocols are blocked for client SDK callers (anonymous, account session, JWT, and OAuth users). Server SDKs using an API key still have access, including to re-enable the protocol. +- **Repeatable provisioning.** Script the protocol set a project should expose and apply it from CI when spinning up a new environment. +- **Environment parity.** Keep dev, staging, and production in sync by running the same enable/disable script against each project. diff --git a/src/routes/docs/products/project/services/+page.markdoc b/src/routes/docs/products/project/services/+page.markdoc new file mode 100644 index 0000000000..3df5a748cc --- /dev/null +++ b/src/routes/docs/products/project/services/+page.markdoc @@ -0,0 +1,296 @@ +--- +layout: article +title: Services +description: Enable or disable individual Appwrite services on your project programmatically using server SDKs. +--- + +Each Appwrite project ships with the full set of services enabled by default: Account, TablesDB, Storage, Functions, and so on. You can disable any service your clients don't use to remove it from the client-facing API. Disabled services remain accessible to server SDKs using an API key. + +Services can be toggled from the Appwrite Console, or programmatically through any server SDK using the Project service. + +# Manage from the Console {% #manage-console %} + +{% only_dark %} +![Project services in the Appwrite Console](/images/docs/project/dark/services.png) +{% /only_dark %} +{% only_light %} +![Project services in the Appwrite Console](/images/docs/project/services.png) +{% /only_light %} + +To toggle a service manually: + +1. Open your project in the Appwrite Console. +2. Open **Settings** from the bottom of the side nav. +3. Scroll to the **Services** card. +4. Flip the switch next to the service you want to enable or disable. Use **Disable all** to turn off every optional service at once. + +# Available services {% #available-services %} + +| Service ID | Description | +| --- | --- | +| `account` | User accounts and authentication. | +| `avatars` | App image, icon, and avatar helpers. | +| `tablesdb` | TablesDB tables, columns, and rows. | +| `locale` | Locale and geographic helpers. | +| `health` | Health checks and status. | +| `project` | Project configuration. | +| `storage` | File storage buckets and files. | +| `teams` | Teams and shared resource access. | +| `users` | User administration via server SDKs. | +| `sites` | Sites hosting and deployments. | +| `functions` | Cloud Functions. | +| `proxy` | Custom domain proxy. | +| `graphql` | GraphQL endpoint. | +| `migrations` | Third-party data migrations. | +| `messaging` | Push, SMS, and email messaging. | +| `databases` | Legacy Databases collections and documents. | + +# Update a service {% #update-service %} + +The example below disables the Account service. Pass `enabled: true` to re-enable it. + +{% info title="Required scope" %} +The API key used for this call needs the `project.write` scope. +{% /info %} + +{% multicode %} +```server-nodejs +import { Client, Project, ServiceId } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateService({ + serviceId: ServiceId.Account, + enabled: false +}); +``` +```server-deno +import { Client, Project, ServiceId } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const project = new Project(client); + +const result = await project.updateService({ + serviceId: ServiceId.Account, + enabled: false +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$project = new Project($client); + +$result = $project->updateService( + serviceId: ServiceId::ACCOUNT(), + enabled: false +); +``` +```server-python +from appwrite.client import Client +from appwrite.enums import ServiceId +from appwrite.services.project import Project + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +project = Project(client) + +result = project.update_service( + service_id = ServiceId.ACCOUNT, + enabled = False +) +``` +```server-ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +project = Project.new(client) + +response = project.update_service( + service_id: ServiceId::ACCOUNT, + enabled: false +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Enums; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Project project = new Project(client); + +var result = await project.UpdateService( + serviceId: ServiceId.Account, + enabled: false +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart' as enums; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Project project = Project(client); + +final result = await project.updateService( + serviceId: enums.ServiceId.account, + enabled: false, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.enums.ServiceId +import io.appwrite.services.Project + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +val project = Project(client) + +val response = project.updateService( + serviceId = ServiceId.ACCOUNT, + enabled = false +) +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.enums.ServiceId; +import io.appwrite.services.Project; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey(""); + +Project project = new Project(client); + +project.updateService( + ServiceId.ACCOUNT, // serviceId + false, // enabled + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); + }) +); +``` +```server-swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let project = Project(client) + +let result = try await project.updateService( + serviceId: .account, + enabled: false +) +``` +```server-go +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + service := appwrite.NewProject(client) + result, err := service.UpdateService( + "account", + false, + ) + + if err != nil { + panic(err) + } + + fmt.Println(result) +} +``` +```server-rust +use appwrite::Client; +use appwrite::enums::ServiceId; +use appwrite::services::project::Project; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let project = Project::new(&client); + + let result = project.update_service( + ServiceId::Account, + false, + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite project update-service \ + --service-id account \ + --enabled false +``` +{% /multicode %} + +# Benefits {% #benefits %} + +- **Shrink the client surface area.** Disable services your client apps don't use so they're no longer callable from client SDKs. +- **Server-only access.** Disabled services stay reachable from server SDKs using an API key, useful when you want a service available to your backend but hidden from clients. +- **Repeatable provisioning.** Script the service set a project should expose and apply it from CI when spinning up a new environment. diff --git a/static/images/docs/project/auth-methods.png b/static/images/docs/project/auth-methods.png new file mode 100644 index 0000000000..77427ae60c Binary files /dev/null and b/static/images/docs/project/auth-methods.png differ diff --git a/static/images/docs/platform/create-api-key.png b/static/images/docs/project/create-api-key.png similarity index 100% rename from static/images/docs/platform/create-api-key.png rename to static/images/docs/project/create-api-key.png diff --git a/static/images/docs/project/dark/auth-methods.png b/static/images/docs/project/dark/auth-methods.png new file mode 100644 index 0000000000..9b0e798d53 Binary files /dev/null and b/static/images/docs/project/dark/auth-methods.png differ diff --git a/static/images/docs/platform/dark/create-api-key.png b/static/images/docs/project/dark/create-api-key.png similarity index 100% rename from static/images/docs/platform/dark/create-api-key.png rename to static/images/docs/project/dark/create-api-key.png diff --git a/static/images/docs/project/dark/mock-phones.png b/static/images/docs/project/dark/mock-phones.png new file mode 100644 index 0000000000..b7e042783d Binary files /dev/null and b/static/images/docs/project/dark/mock-phones.png differ diff --git a/static/images/docs/project/dark/platforms.png b/static/images/docs/project/dark/platforms.png new file mode 100644 index 0000000000..c4dab9f948 Binary files /dev/null and b/static/images/docs/project/dark/platforms.png differ diff --git a/static/images/docs/project/dark/policies.png b/static/images/docs/project/dark/policies.png new file mode 100644 index 0000000000..7626af6653 Binary files /dev/null and b/static/images/docs/project/dark/policies.png differ diff --git a/static/images/docs/project/dark/protocols.png b/static/images/docs/project/dark/protocols.png new file mode 100644 index 0000000000..108fa3dde9 Binary files /dev/null and b/static/images/docs/project/dark/protocols.png differ diff --git a/static/images/docs/project/dark/services.png b/static/images/docs/project/dark/services.png new file mode 100644 index 0000000000..a8b8e7aa7d Binary files /dev/null and b/static/images/docs/project/dark/services.png differ diff --git a/static/images/docs/project/mock-phones.png b/static/images/docs/project/mock-phones.png new file mode 100644 index 0000000000..cab874ac6d Binary files /dev/null and b/static/images/docs/project/mock-phones.png differ diff --git a/static/images/docs/project/platforms.png b/static/images/docs/project/platforms.png new file mode 100644 index 0000000000..8617e14b24 Binary files /dev/null and b/static/images/docs/project/platforms.png differ diff --git a/static/images/docs/project/policies.png b/static/images/docs/project/policies.png new file mode 100644 index 0000000000..da928b218d Binary files /dev/null and b/static/images/docs/project/policies.png differ diff --git a/static/images/docs/project/protocols.png b/static/images/docs/project/protocols.png new file mode 100644 index 0000000000..06be65c0ec Binary files /dev/null and b/static/images/docs/project/protocols.png differ diff --git a/static/images/docs/project/services.png b/static/images/docs/project/services.png new file mode 100644 index 0000000000..fdd105f6ca Binary files /dev/null and b/static/images/docs/project/services.png differ