Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 28.2.0

* Added: `account` passkey methods `listPasskeys`, `createPasskey`, `getPasskey`, `updatePasskey`, `deletePasskey` and `updatePasskeyVerification`
* Added: `account.createPasskeyToken` and `account.updatePasskeyToken` for passkey sign-in
* Added: `Passkey`, `PasskeyList`, `PasskeyChallenge` and `TokenSecret` models

## 28.1.0

* Added: `Apps` service to create and manage OAuth2 apps, their secrets, keys, and installations
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { Client, Account } from 'appwrite';
To install with a CDN (content delivery network) add the following scripts to the bottom of your <body> tag, but before you use any Appwrite services:

```html
<script src="https://cdn.jsdelivr.net/npm/appwrite@28.1.0"></script>
<script src="https://cdn.jsdelivr.net/npm/appwrite@28.2.0"></script>
```

## Getting Started
Expand Down
13 changes: 13 additions & 0 deletions docs/examples/account/create-passkey-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.createPasskeyToken();

console.log(result);
```
16 changes: 16 additions & 0 deletions docs/examples/account/create-passkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.createPasskey({
passkeyId: '<PASSKEY_ID>', // optional
name: '<NAME>', // optional
});

console.log(result);
```
15 changes: 15 additions & 0 deletions docs/examples/account/delete-passkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.deletePasskey({
passkeyId: '<PASSKEY_ID>',
});

console.log(result);
```
15 changes: 15 additions & 0 deletions docs/examples/account/get-passkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.getPasskey({
passkeyId: '<PASSKEY_ID>',
});

console.log(result);
```
16 changes: 16 additions & 0 deletions docs/examples/account/list-passkeys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.listPasskeys({
queries: [], // optional
total: false, // optional
});

console.log(result);
```
16 changes: 16 additions & 0 deletions docs/examples/account/update-passkey-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.updatePasskeyToken({
challengeId: '<CHALLENGE_ID>',
credential: {},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Show an authenticator credential in the example

As written, this sends an empty object as the authenticator assertion, which the server rejects even after the challenge ID is filled in. Could the example show the JSON from navigator.credentials.get() (and the corresponding navigator.credentials.create() result in update-passkey-verification.md) so users can complete these calls?

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/examples/account/update-passkey-token.md
Line: 12

Comment:
**Show an authenticator credential in the example**

As written, this sends an empty object as the authenticator assertion, which the server rejects even after the challenge ID is filled in. Could the example show the JSON from `navigator.credentials.get()` (and the corresponding `navigator.credentials.create()` result in `update-passkey-verification.md`) so users can complete these calls?

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

🟡 Minor · documentation · Reply if this doesn't apply.

});

console.log(result);
```
16 changes: 16 additions & 0 deletions docs/examples/account/update-passkey-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.updatePasskeyVerification({
passkeyId: '<PASSKEY_ID>',
credential: {},
});

console.log(result);
```
16 changes: 16 additions & 0 deletions docs/examples/account/update-passkey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```javascript
import { Client, Account } from 'appwrite';

const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID

const account = new Account(client);

const result = await account.updatePasskey({
passkeyId: '<PASSKEY_ID>',
name: '<NAME>',
});

console.log(result);
```
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "appwrite",
"homepage": "https://appwrite.io/support",
"description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API",
"version": "28.1.0",
"version": "28.2.0",
"license": "BSD-3-Clause",
"main": "dist/cjs/sdk.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ class Client {
'x-sdk-name': 'Web',
'x-sdk-platform': 'client',
'x-sdk-language': 'web',
'x-sdk-version': '28.1.0',
'x-sdk-version': '28.2.0',
'X-Appwrite-Response-Format': '2.3.0',
};

Expand Down
96 changes: 96 additions & 0 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,102 @@ export namespace Models {
expire: string;
};

/**
* Token Secret
*/
export type TokenSecret = {
/**
* Token ID.
*/
$id: string;
/**
* Token creation date in ISO 8601 format.
*/
$createdAt: string;
/**
* User ID.
*/
userId: string;
/**
* Token secret key. Exchange it for a session with the create session endpoint.
*/
secret: string;
/**
* Token expiration date in ISO 8601 format.
*/
expire: string;
/**
* Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email.
*/
phrase: string;
};

/**
* Passkey
*/
export type Passkey = {
/**
* Passkey ID.
*/
$id: string;
/**
* Passkey creation date in ISO 8601 format.
*/
$createdAt: string;
/**
* Passkey update date in ISO 8601 format.
*/
$updatedAt: string;
/**
* Passkey name.
*/
name: string;
/**
* Most recent sign-in with this passkey in ISO 8601 format. Empty until the passkey is used to sign in.
*/
accessedAt: string;
};

/**
* Passkey Challenge
*/
export type PasskeyChallenge = {
/**
* Challenge ID. When signing in, pass it back with the credential to receive a token.
*/
$id: string;
/**
* Challenge creation date in ISO 8601 format.
*/
$createdAt: string;
/**
* ID of the passkey being registered. Empty for sign-in challenges.
*/
passkeyId: string;
/**
* Challenge expiration date in ISO 8601 format.
*/
expire: string;
/**
* WebAuthn options in JSON form. Pass them to `PublicKeyCredential.parseCreationOptionsFromJSON()` when registering, or `PublicKeyCredential.parseRequestOptionsFromJSON()` when signing in.
*/
publicKey: object;
};

/**
* Passkeys List
*/
export type PasskeyList = {
/**
* Total number of passkeys that matched your query.
*/
total: number;
/**
* List of passkeys.
*/
passkeys: Passkey[];
};

/**
* MFA Recovery Codes
*/
Expand Down
Loading
Loading