Merge branch 'appwrite:master' into feat-926-oauth2-microsoft-tenant-config
This commit is contained in:
commit
7f52116a17
|
@ -32,7 +32,7 @@ ENV DEBUG=$DEBUG
|
|||
ENV PHP_REDIS_VERSION=5.3.5 \
|
||||
PHP_MONGODB_VERSION=1.9.1 \
|
||||
PHP_SWOOLE_VERSION=v4.8.5 \
|
||||
PHP_IMAGICK_VERSION=3.5.1 \
|
||||
PHP_IMAGICK_VERSION=3.7.0 \
|
||||
PHP_YAML_VERSION=2.2.2 \
|
||||
PHP_MAXMINDDB_VERSION=v1.11.0
|
||||
|
||||
|
|
|
@ -2209,6 +2209,7 @@ $collections = [
|
|||
],
|
||||
],
|
||||
],
|
||||
|
||||
'stats' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'stats',
|
||||
|
@ -2294,6 +2295,7 @@ $collections = [
|
|||
],
|
||||
],
|
||||
],
|
||||
|
||||
'realtime' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'realtime',
|
||||
|
|
|
@ -131,6 +131,16 @@ return [ // Ordered by ABC.
|
|||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'notion' => [
|
||||
'name' => 'Notion',
|
||||
'developers' => 'https://developers.notion.com/docs',
|
||||
'icon' => 'icon-notion',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'paypal' => [
|
||||
'name' => 'PayPal',
|
||||
'developers' => 'https://developer.paypal.com/docs/api/overview/',
|
||||
|
|
|
@ -479,7 +479,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT);
|
||||
$sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_USERS);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
@ -652,7 +652,7 @@ App::post('/v1/account/sessions/magic-url')
|
|||
if ($limit !== 0) {
|
||||
$sum = $dbForProject->count('users', [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false]),
|
||||
], APP_LIMIT_COUNT);
|
||||
], APP_LIMIT_USERS);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
@ -924,7 +924,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
if ($limit !== 0) {
|
||||
$sum = $dbForProject->count('users', [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false]),
|
||||
], APP_LIMIT_COUNT);
|
||||
], APP_LIMIT_USERS);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
|
|
@ -461,7 +461,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
|
|||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PROJECT)
|
||||
->param('projectId', '', new UID(), 'Project unique ID.')
|
||||
->param('limit', false, new Integer(true), 'Set the max number of users allowed in this project. Use 0 for unlimited.')
|
||||
->param('limit', false, new Range(0, APP_LIMIT_USERS), 'Set the max number of users allowed in this project. Use 0 for unlimited.')
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function ($projectId, $limit, $response, $dbForConsole) {
|
||||
|
|
|
@ -725,6 +725,11 @@ App::delete('/v1/users/:userId')
|
|||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// clone user object to send to workers
|
||||
$clone = clone $user;
|
||||
|
||||
|
@ -733,6 +738,8 @@ App::delete('/v1/users/:userId')
|
|||
->setAttribute("email", null)
|
||||
->setAttribute("password", null)
|
||||
->setAttribute("deleted", true)
|
||||
->setAttribute("tokens", [])
|
||||
->setAttribute("search", null)
|
||||
;
|
||||
|
||||
$dbForProject->updateDocument('users', $userId, $user);
|
||||
|
|
|
@ -453,7 +453,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
<div class="box margin-bottom">
|
||||
<ul data-ls-loop="members.memberships" data-ls-as="member" class="list">
|
||||
<li class="clear">
|
||||
<form class="pull-end"
|
||||
<form class="pull-end" data-ls-if="{{account.$id}} !== {{member.userId}}"
|
||||
data-analytics
|
||||
data-analytics-activity
|
||||
data-analytics-event="submit"
|
||||
|
@ -473,7 +473,33 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
<input name="teamId" data-ls-attrs="id=leave-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
|
||||
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
|
||||
<button class="danger">Leave</button>
|
||||
<button data-ls-if="1 === {{members.memberships.length}}" class="danger" disabled>Remove</button>
|
||||
<button data-ls-if="1 < {{members.memberships.length}}" class="danger">Remove</button>
|
||||
</form>
|
||||
|
||||
<form class="pull-end" data-ls-if="{{account.$id}} === {{member.userId}}"
|
||||
data-analytics
|
||||
data-analytics-activity
|
||||
data-analytics-event="submit"
|
||||
data-analytics-category="console"
|
||||
data-analytics-label="Delete Project Membership"
|
||||
data-service="teams.deleteMembership"
|
||||
data-scope="console"
|
||||
data-event="submit"
|
||||
data-success="alert,trigger,redirect"
|
||||
data-confirm="Are you sure you want to remove that user from the team?"
|
||||
data-success-param-alert-text="Member Removed Successfully"
|
||||
data-success-param-trigger-events="teams.deleteMembership"
|
||||
data-success-param-redirect-url="/console"
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to Remove Member"
|
||||
data-failure-param-alert-classname="error">
|
||||
|
||||
<input name="teamId" data-ls-attrs="id=leave-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
|
||||
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
|
||||
<button data-ls-if="1 === {{members.memberships.length}}" class="danger" disabled>Remove</button>
|
||||
<button data-ls-if="1 < {{members.memberships.length}}" class="danger">Remove</button>
|
||||
</form>
|
||||
|
||||
<div data-ls-if="false === {{member.confirm}}" class="pull-end margin-end">
|
||||
|
|
|
@ -355,13 +355,13 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
data-failure-param-alert-text="Failed to update project users limit"
|
||||
data-failure-param-alert-classname="error">
|
||||
|
||||
<input name="limit" id="users-limit" type="number" data-ls-bind="{{console-project.authLimit}}" data-cast-to="numeric" min="0" />
|
||||
<input name="limit" id="users-limit" type="number" data-ls-bind="{{console-project.authLimit}}" data-cast-to="numeric" min="0" max="<?php echo APP_LIMIT_USERS; ?>" />
|
||||
|
||||
<div class="info row thin margin-bottom margin-top">
|
||||
<div class="col span-1">
|
||||
<i class="icon-info-circled text-sign"></i>
|
||||
</div>
|
||||
<div class="col span-11">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.</div>
|
||||
<div class="col span-11">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 <?php echo number_format(APP_LIMIT_USERS); ?>.</div>
|
||||
</div>
|
||||
|
||||
<button>Update</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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: .
|
||||
|
|
|
@ -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.
|
||||
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.
|
||||
|
|
BIN
public/images/users/notion.png
Normal file
BIN
public/images/users/notion.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
148
src/Appwrite/Auth/OAuth2/Notion.php
Normal file
148
src/Appwrite/Auth/OAuth2/Notion.php
Normal file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Auth\OAuth2;
|
||||
|
||||
use Appwrite\Auth\OAuth2;
|
||||
|
||||
class Notion extends OAuth2
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $endpoint = 'https://api.notion.com/v1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $version = '2021-08-16';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $user = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $scopes = [];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName():string
|
||||
{
|
||||
return 'notion';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLoginURL():string
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue