Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user verification journey to auth docs #1548

Merged
merged 15 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/routes/docs/products/auth/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@
{
label: 'Multi-factor authentication',
href: '/docs/products/auth/mfa'
},
{
label: 'User verification',
href: '/docs/products/auth/verification'
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved
}
]
},
Expand Down
282 changes: 282 additions & 0 deletions src/routes/docs/products/auth/verification/+page.markdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
---
layout: article
title: User verification
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved
description: Learn about Appwrite's email and phone verification system, including verification flows and role-based access control.
---

User verification in Appwrite allows you to verify user email addresses and phone numbers. Users don't need to be verified to log in, but you can restrict resource access to verified users only using permissions.

# Email verification {% #email-verification %}
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved

To verify a user's email, first send a verification email with a redirect URL. The verification secrets will be appended as query parameters to the redirect URL:
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved

{% multicode %}
```client-web
import { Client, Account } from "appwrite";

const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>') // Your project ID

const account = new Account(client);

const promise = account.createVerification('https://example.com/verify');

promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
```

```client-flutter
import 'package:appwrite/appwrite.dart';

void main() {
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');

Account account = Account(client);

Future result = account.createVerification(
url: 'https://example.com/verify'
);

result.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
```

```client-apple
import Appwrite

let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

let account = Account(client)

let token = try await account.createVerification(
url: "https://example.com/verify"
)
```

```client-android-kotlin
import io.appwrite.Client
import io.appwrite.services.Account

val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

val account = Account(client)

val response = account.createVerification(
url = "https://example.com/verify"
)
```
{% /multicode %}

After the user clicks the link in the email, they will be redirected to your site with the query parameters `userId` and `secret`. If you're on a mobile platform, you will need to create the appropriate deep link to handle the verification.

Next, implement the verification page that handles the redirect:

{% multicode %}
```client-web
import { Client, Account } from "appwrite";

const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');

const account = new Account(client);

const urlParams = new URLSearchParams(window.location.search);
const secret = urlParams.get('secret');
const userId = urlParams.get('userId');

const promise = account.updateVerification(userId, secret);

promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
```

```client-flutter
import 'package:appwrite/appwrite.dart';

void main() {
Client client = Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>');

Account account = Account(client);

Future result = account.updateVerification(
userId: '<USER_ID>',
secret: '<SECRET>'
);

result.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
```

```client-apple
import Appwrite

let client = Client()
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

let account = Account(client)

let response = try await account.updateVerification(
userId: "<USER_ID>",
secret: "<SECRET>"
)
```

```client-android-kotlin
import io.appwrite.Client
import io.appwrite.services.Account

val client = Client(context)
.setEndpoint("https://cloud.appwrite.io/v1")
.setProject("<PROJECT_ID>")

val account = Account(client)

val response = account.updateVerification(
userId = "<USER_ID>",
secret = "<SECRET>"
)
```
{% /multicode %}

# Phone verification {% #phone-verification %}
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved

To verify a phone number, first ensure the user has a phone number set on their account:

{% multicode %}
```client-web
const response = await account.updatePhone(
'+12065550100', // phone
'password' // password
);
```

```client-flutter
Future result = account.updatePhone(
phone: '+12065550100',
password: 'password'
);

result.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
```

```client-apple
let response = try await account.updatePhone(
phone: "+12065550100",
password: "password"
)
```

```client-android-kotlin
val response = account.updatePhone(
phone = "+12065550100",
password = "password"
)
```
{% /multicode %}

Then initiate verification by calling `createPhoneVerification`:

{% multicode %}
```client-web
const response = await account.createPhoneVerification();
```

```client-flutter
Future result = account.createPhoneVerification();

result.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
```

```client-apple
let response = try await account.createPhoneVerification()
```

```client-android-kotlin
val response = account.createPhoneVerification()
```
{% /multicode %}

After the user receives the verification code, complete verification by calling `updatePhoneVerification`:

{% multicode %}
```client-web
const response = await account.updatePhoneVerification(
'[USER_ID]', // userId
'[SECRET]' // secret
);
```

```client-flutter
Future result = account.updatePhoneVerification(
userId: '[USER_ID]',
secret: '[SECRET]'
);

result.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
```

```client-apple
let response = try await account.updatePhoneVerification(
userId: "[USER_ID]",
secret: "[SECRET]"
)
```

```client-android-kotlin
val response = account.updatePhoneVerification(
userId = "[USER_ID]",
secret = "[SECRET]"
)
```
{% /multicode %}

# Role-based access {% #role-based-access %}
ebenezerdon marked this conversation as resolved.
Show resolved Hide resolved

You can restrict resource access to verified users only using permissions through the `user([USER_ID], "verified")` role. This role is automatically assigned after successful verification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would restrict for a single user. Let's also mention users('verified') to restrict access to all/any verified user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done


# Verification events {% #verification-events %}

The following events are triggered during the verification process:

- `users.*.verification.*` - Triggers on any user's verification token event
- `users.*.verification.*.create` - Triggers when a verification token for a user is created
- `users.*.verification.*.update` - Triggers when a verification token for a user is validated

Each event returns a Token Object.
Loading