mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Merge branch '1.6.x' of github.com:appwrite/appwrite into fix-maintenance-job
This commit is contained in:
commit
c3e2a3fac2
7 changed files with 67 additions and 60 deletions
|
|
@ -349,11 +349,6 @@ return [
|
||||||
'description' => 'Team with the requested ID could not be found.',
|
'description' => 'Team with the requested ID could not be found.',
|
||||||
'code' => 404,
|
'code' => 404,
|
||||||
],
|
],
|
||||||
Exception::TEAM_INVITE_ALREADY_EXISTS => [
|
|
||||||
'name' => Exception::TEAM_INVITE_ALREADY_EXISTS,
|
|
||||||
'description' => 'User has already been invited or is already a member of this team',
|
|
||||||
'code' => 409,
|
|
||||||
],
|
|
||||||
Exception::TEAM_INVITE_NOT_FOUND => [
|
Exception::TEAM_INVITE_NOT_FOUND => [
|
||||||
'name' => Exception::TEAM_INVITE_NOT_FOUND,
|
'name' => Exception::TEAM_INVITE_NOT_FOUND,
|
||||||
'description' => 'The requested team invitation could not be found.',
|
'description' => 'The requested team invitation could not be found.',
|
||||||
|
|
|
||||||
|
|
@ -546,47 +546,58 @@ App::post('/v1/teams/:teamId/memberships')
|
||||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
|
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
|
||||||
}
|
}
|
||||||
|
|
||||||
$secret = Auth::tokenGenerator();
|
$membership = $dbForProject->findOne('memberships', [
|
||||||
|
Query::equal('userInternalId', [$invitee->getInternalId()]),
|
||||||
$membershipId = ID::unique();
|
Query::equal('teamInternalId', [$team->getInternalId()]),
|
||||||
$membership = new Document([
|
|
||||||
'$id' => $membershipId,
|
|
||||||
'$permissions' => [
|
|
||||||
Permission::read(Role::any()),
|
|
||||||
Permission::update(Role::user($invitee->getId())),
|
|
||||||
Permission::update(Role::team($team->getId(), 'owner')),
|
|
||||||
Permission::delete(Role::user($invitee->getId())),
|
|
||||||
Permission::delete(Role::team($team->getId(), 'owner')),
|
|
||||||
],
|
|
||||||
'userId' => $invitee->getId(),
|
|
||||||
'userInternalId' => $invitee->getInternalId(),
|
|
||||||
'teamId' => $team->getId(),
|
|
||||||
'teamInternalId' => $team->getInternalId(),
|
|
||||||
'roles' => $roles,
|
|
||||||
'invited' => DateTime::now(),
|
|
||||||
'joined' => ($isPrivilegedUser || $isAppUser) ? DateTime::now() : null,
|
|
||||||
'confirm' => ($isPrivilegedUser || $isAppUser),
|
|
||||||
'secret' => Auth::hash($secret),
|
|
||||||
'search' => implode(' ', [$membershipId, $invitee->getId()])
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
|
if ($membership->isEmpty()) {
|
||||||
try {
|
$secret = Auth::tokenGenerator();
|
||||||
$membership = Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership));
|
|
||||||
} catch (Duplicate $th) {
|
|
||||||
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$membershipId = ID::unique();
|
||||||
|
$membership = new Document([
|
||||||
|
'$id' => $membershipId,
|
||||||
|
'$permissions' => [
|
||||||
|
Permission::read(Role::any()),
|
||||||
|
Permission::update(Role::user($invitee->getId())),
|
||||||
|
Permission::update(Role::team($team->getId(), 'owner')),
|
||||||
|
Permission::delete(Role::user($invitee->getId())),
|
||||||
|
Permission::delete(Role::team($team->getId(), 'owner')),
|
||||||
|
],
|
||||||
|
'userId' => $invitee->getId(),
|
||||||
|
'userInternalId' => $invitee->getInternalId(),
|
||||||
|
'teamId' => $team->getId(),
|
||||||
|
'teamInternalId' => $team->getInternalId(),
|
||||||
|
'roles' => $roles,
|
||||||
|
'invited' => DateTime::now(),
|
||||||
|
'joined' => ($isPrivilegedUser || $isAppUser) ? DateTime::now() : null,
|
||||||
|
'confirm' => ($isPrivilegedUser || $isAppUser),
|
||||||
|
'secret' => Auth::hash($secret),
|
||||||
|
'search' => implode(' ', [$membershipId, $invitee->getId()])
|
||||||
|
]);
|
||||||
|
|
||||||
|
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||||
|
Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)) :
|
||||||
|
$dbForProject->createDocument('memberships', $membership);
|
||||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||||
|
|
||||||
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
$membership->setAttribute('invited', DateTime::now());
|
||||||
$membership = $dbForProject->createDocument('memberships', $membership);
|
|
||||||
} catch (Duplicate $th) {
|
if ($isPrivilegedUser || $isAppUser) {
|
||||||
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
|
$membership->setAttribute('joined', DateTime::now());
|
||||||
|
$membership->setAttribute('confirm', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||||
|
Authorization::skip(fn () => $dbForProject->updateDocument('memberships', $membership->getId(), $membership)) :
|
||||||
|
$dbForProject->updateDocument('memberships', $membership->getId(), $membership);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($isPrivilegedUser || $isAppUser) {
|
||||||
|
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
||||||
|
} else {
|
||||||
$url = Template::parseURL($url);
|
$url = Template::parseURL($url);
|
||||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||||
$url = Template::unParseURL($url);
|
$url = Template::unParseURL($url);
|
||||||
|
|
@ -656,7 +667,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||||
'owner' => $user->getAttribute('name'),
|
'owner' => $user->getAttribute('name'),
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
||||||
'user' => $user->getAttribute('name'),
|
'user' => $name,
|
||||||
'team' => $team->getAttribute('name'),
|
'team' => $team->getAttribute('name'),
|
||||||
'redirect' => $url,
|
'redirect' => $url,
|
||||||
'project' => $projectName
|
'project' => $projectName
|
||||||
|
|
@ -668,8 +679,8 @@ App::post('/v1/teams/:teamId/memberships')
|
||||||
->setRecipient($invitee->getAttribute('email'))
|
->setRecipient($invitee->getAttribute('email'))
|
||||||
->setName($invitee->getAttribute('name'))
|
->setName($invitee->getAttribute('name'))
|
||||||
->setVariables($emailVariables)
|
->setVariables($emailVariables)
|
||||||
->trigger()
|
->trigger();
|
||||||
;
|
|
||||||
} elseif (!empty($phone)) {
|
} elseif (!empty($phone)) {
|
||||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
"utopia-php/domains": "0.5.*",
|
"utopia-php/domains": "0.5.*",
|
||||||
"utopia-php/dsn": "0.2.1",
|
"utopia-php/dsn": "0.2.1",
|
||||||
"utopia-php/framework": "0.33.*",
|
"utopia-php/framework": "0.33.*",
|
||||||
"utopia-php/fetch": "0.2.*",
|
"utopia-php/fetch": "0.3.*",
|
||||||
"utopia-php/image": "0.7.*",
|
"utopia-php/image": "0.7.*",
|
||||||
"utopia-php/locale": "0.4.*",
|
"utopia-php/locale": "0.4.*",
|
||||||
"utopia-php/logger": "0.6.*",
|
"utopia-php/logger": "0.6.*",
|
||||||
|
|
|
||||||
14
composer.lock
generated
14
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "3853435a659889e86c16764046950bed",
|
"content-hash": "92b40e75d531c98b72508dd104eeab0d",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adhocore/jwt",
|
"name": "adhocore/jwt",
|
||||||
|
|
@ -3639,16 +3639,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/fetch",
|
"name": "utopia-php/fetch",
|
||||||
"version": "0.2.1",
|
"version": "0.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/utopia-php/fetch.git",
|
"url": "https://github.com/utopia-php/fetch.git",
|
||||||
"reference": "1423c0ee3eef944d816ca6e31706895b585aea82"
|
"reference": "02b12c05aec13399dcc2da8d51f908e328ab63f4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/1423c0ee3eef944d816ca6e31706895b585aea82",
|
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/02b12c05aec13399dcc2da8d51f908e328ab63f4",
|
||||||
"reference": "1423c0ee3eef944d816ca6e31706895b585aea82",
|
"reference": "02b12c05aec13399dcc2da8d51f908e328ab63f4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -3672,9 +3672,9 @@
|
||||||
"description": "A simple library that provides an interface for making HTTP Requests.",
|
"description": "A simple library that provides an interface for making HTTP Requests.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/utopia-php/fetch/issues",
|
"issues": "https://github.com/utopia-php/fetch/issues",
|
||||||
"source": "https://github.com/utopia-php/fetch/tree/0.2.1"
|
"source": "https://github.com/utopia-php/fetch/tree/0.3.0"
|
||||||
},
|
},
|
||||||
"time": "2024-03-18T11:50:59+00:00"
|
"time": "2025-01-17T06:11:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/framework",
|
"name": "utopia-php/framework",
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ class Exception extends \Exception
|
||||||
|
|
||||||
/** Teams */
|
/** Teams */
|
||||||
public const TEAM_NOT_FOUND = 'team_not_found';
|
public const TEAM_NOT_FOUND = 'team_not_found';
|
||||||
public const TEAM_INVITE_ALREADY_EXISTS = 'team_invite_already_exists';
|
|
||||||
public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found';
|
public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found';
|
||||||
public const TEAM_INVALID_SECRET = 'team_invalid_secret';
|
public const TEAM_INVALID_SECRET = 'team_invalid_secret';
|
||||||
public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch';
|
public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch';
|
||||||
|
|
|
||||||
|
|
@ -291,10 +291,7 @@ trait TeamsBaseClient
|
||||||
$this->assertEquals($secondName, $lastEmail['to'][0]['name']);
|
$this->assertEquals($secondName, $lastEmail['to'][0]['name']);
|
||||||
$this->assertEquals('Invitation to ' . $teamName . ' Team at ' . $this->getProject()['name'], $lastEmail['subject']);
|
$this->assertEquals('Invitation to ' . $teamName . ' Team at ' . $this->getProject()['name'], $lastEmail['subject']);
|
||||||
|
|
||||||
/**
|
// test for resending invitation
|
||||||
* Test for FAILURE
|
|
||||||
*/
|
|
||||||
|
|
||||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||||
'content-type' => 'application/json',
|
'content-type' => 'application/json',
|
||||||
'x-appwrite-project' => $this->getProject()['$id'],
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
|
@ -305,7 +302,11 @@ trait TeamsBaseClient
|
||||||
'url' => 'http://localhost:5000/join-us#title'
|
'url' => 'http://localhost:5000/join-us#title'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertEquals(409, $response['headers']['status-code']);
|
$this->assertEquals(201, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for FAILURE
|
||||||
|
*/
|
||||||
|
|
||||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||||
'content-type' => 'application/json',
|
'content-type' => 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -185,10 +185,7 @@ trait TeamsBaseServer
|
||||||
// $this->assertContains('team:'.$teamUid.'/admin', $response['body']['roles']);
|
// $this->assertContains('team:'.$teamUid.'/admin', $response['body']['roles']);
|
||||||
// $this->assertContains('team:'.$teamUid.'/editor', $response['body']['roles']);
|
// $this->assertContains('team:'.$teamUid.'/editor', $response['body']['roles']);
|
||||||
|
|
||||||
/**
|
// test for resending invitation
|
||||||
* Test for FAILURE
|
|
||||||
*/
|
|
||||||
|
|
||||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||||
'content-type' => 'application/json',
|
'content-type' => 'application/json',
|
||||||
'x-appwrite-project' => $this->getProject()['$id'],
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
|
@ -199,7 +196,11 @@ trait TeamsBaseServer
|
||||||
'url' => 'http://localhost:5000/join-us#title'
|
'url' => 'http://localhost:5000/join-us#title'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertEquals(409, $response['headers']['status-code']);
|
$this->assertEquals(201, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for FAILURE
|
||||||
|
*/
|
||||||
|
|
||||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||||
'content-type' => 'application/json',
|
'content-type' => 'application/json',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue