This limit will prevent new users from signing up for your project, no matter what auth method has been used. You will still be able to create users and team memberships from your Appwrite console. For an unlimited amount of users, set the limit to 0.
+
This limit will prevent new users from signing up for your project, no matter what auth method has been used. You will still be able to create users and team memberships from your Appwrite console. For an unlimited amount of users, set the limit to 0. Max limit is .
diff --git a/app/workers/deletes.php b/app/workers/deletes.php
index f4fd667d2a..8caf7ddb23 100644
--- a/app/workers/deletes.php
+++ b/app/workers/deletes.php
@@ -188,9 +188,22 @@ class DeletesV1 extends Worker
*/
protected function deleteUser(Document $document, string $projectId): void
{
+ /**
+ * DO NOT DELETE THE USER RECORD ITSELF.
+ * WE RETAIN THE USER RECORD TO RESERVE THE USER ID AND ENSURE THAT THE USER ID IS NOT REUSED.
+ */
+
$userId = $document->getId();
+ $user = $this->getProjectDB($projectId)->getDocument('users', $userId);
+
+ // Delete all sessions of this user from the sessions table and update the sessions field of the user record
+ $this->deleteByGroup('sessions', [
+ new Query('userId', Query::TYPE_EQUAL, [$userId])
+ ], $this->getProjectDB($projectId));
+
+ $user->setAttribute('sessions', []);
+ $updated = Authorization::skip(fn() => $this->getProjectDB($projectId)->updateDocument('users', $userId, $user));
- // Tokens and Sessions removed with user document
// Delete Memberships and decrement team membership counts
$this->deleteByGroup('memberships', [
new Query('userId', Query::TYPE_EQUAL, [$userId])
diff --git a/docker-compose.yml b/docker-compose.yml
index c90b38fc5f..1ac7e1b0b0 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -412,11 +412,7 @@ services:
- _APP_MAINTENANCE_RETENTION_AUDIT
appwrite-usage:
- entrypoint:
- - php
- - -e
- - /usr/src/code/app/cli.php
- - usage
+ entrypoint: usage
container_name: appwrite-usage
build:
context: .
diff --git a/docs/references/teams/update-team-membership-status.md b/docs/references/teams/update-team-membership-status.md
index ab8f4ca36a..2788448e51 100644
--- a/docs/references/teams/update-team-membership-status.md
+++ b/docs/references/teams/update-team-membership-status.md
@@ -1 +1,3 @@
-Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.
\ No newline at end of file
+Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.
+
+If the request is successful, a session for the user is automatically created.
diff --git a/public/images/users/notion.png b/public/images/users/notion.png
new file mode 100644
index 0000000000..a8694653ca
Binary files /dev/null and b/public/images/users/notion.png differ
diff --git a/src/Appwrite/Auth/OAuth2/Notion.php b/src/Appwrite/Auth/OAuth2/Notion.php
new file mode 100644
index 0000000000..748e7958ed
--- /dev/null
+++ b/src/Appwrite/Auth/OAuth2/Notion.php
@@ -0,0 +1,148 @@
+endpoint . '/oauth/authorize?'. \http_build_query([
+ 'client_id' => $this->appID,
+ 'redirect_uri' => $this->callback,
+ 'response_type' => 'code',
+ 'state' => \json_encode($this->state),
+ 'owner' => 'user'
+ ]);
+ }
+
+ /**
+ * @param string $code
+ *
+ * @return string
+ */
+ public function getAccessToken(string $code):string
+ {
+ $headers = [
+ "Authorization: Basic " . \base64_encode($this->appID . ":" . $this->appSecret),
+ ];
+
+ $response = $this->request(
+ 'POST',
+ $this->endpoint . '/oauth/token',
+ $headers,
+ \http_build_query([
+ 'grant_type' => 'authorization_code',
+ 'redirect_uri' => $this->callback,
+ 'code' => $code
+ ])
+ );
+
+ $response = \json_decode($response, true);
+
+ if (isset($response['access_token'])) {
+ return $response['access_token'];
+ }
+
+ return '';
+ }
+
+ /**
+ * @param $accessToken
+ *
+ * @return string
+ */
+ public function getUserID(string $accessToken):string
+ {
+ $response = $this->getUser($accessToken);
+
+ if (isset($response['bot']['owner']['user']['id'])) {
+ return $response['bot']['owner']['user']['id'];
+ }
+
+ return '';
+ }
+
+ /**
+ * @param $accessToken
+ *
+ * @return string
+ */
+ public function getUserEmail(string $accessToken):string
+ {
+ $response = $this->getUser($accessToken);
+
+ if(isset($response['bot']['owner']['user']['person']['email'])){
+ return $response['bot']['owner']['user']['person']['email'];
+ }
+
+ return '';
+ }
+
+ /**
+ * @param $accessToken
+ *
+ * @return string
+ */
+ public function getUserName(string $accessToken):string
+ {
+ $response = $this->getUser($accessToken);
+
+ if (isset($response['bot']['owner']['user']['name'])) {
+ return $response['bot']['owner']['user']['name'];
+ }
+
+ return '';
+ }
+
+ /**
+ * @param string $accessToken
+ *
+ * @return array
+ */
+ protected function getUser(string $accessToken)
+ {
+ $headers = [
+ 'Notion-Version: ' . $this->version,
+ 'Authorization: Bearer '.\urlencode($accessToken)
+ ];
+
+ if (empty($this->user)) {
+ $this->user = \json_decode($this->request('GET', $this->endpoint . '/users/me', $headers), true);
+ }
+
+ return $this->user;
+ }
+}