mirror of
https://github.com/appwrite/appwrite
synced 2026-05-06 06:48:22 +00:00
Merge pull request #8718 from appwrite/fix-oauth-trigger-create-user-event
fix: trigger create user event
This commit is contained in:
commit
51274ba709
9 changed files with 202 additions and 145 deletions
|
|
@ -274,7 +274,6 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
|||
App::post('/v1/account')
|
||||
->desc('Create account')
|
||||
->groups(['api', 'account', 'auth'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'sessions.write')
|
||||
->label('auth.type', 'emailPassword')
|
||||
->label('audits.event', 'user.create')
|
||||
|
|
@ -297,9 +296,8 @@ App::post('/v1/account')
|
|||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
|
||||
$email = \strtolower($email);
|
||||
if ('console' === $project->getId()) {
|
||||
|
|
@ -409,8 +407,6 @@ App::post('/v1/account')
|
|||
Authorization::setRole(Role::user($user->getId())->toString());
|
||||
Authorization::setRole(Role::users()->toString());
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($user, Response::MODEL_ACCOUNT);
|
||||
|
|
@ -442,7 +438,6 @@ App::get('/v1/account')
|
|||
App::delete('/v1/account')
|
||||
->desc('Delete account')
|
||||
->groups(['api', 'account'])
|
||||
->label('event', 'users.[userId].delete')
|
||||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.delete')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -1499,6 +1494,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'providerType' => MESSAGE_TYPE_EMAIL,
|
||||
'identifier' => $email,
|
||||
]));
|
||||
|
||||
} catch (Duplicate) {
|
||||
$failureRedirect(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ use Utopia\Validator\Text;
|
|||
use Utopia\Validator\WhiteList;
|
||||
|
||||
/** TODO: Remove function when we move to using utopia/platform */
|
||||
function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks): Document
|
||||
function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Hooks $hooks): Document
|
||||
{
|
||||
$plaintextPassword = $password;
|
||||
$hashOptionsObject = (\is_string($hashOptions)) ? \json_decode($hashOptions, true) : $hashOptions; // Cast to JSON array
|
||||
|
|
@ -176,15 +176,12 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
|||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
App::post('/v1/users')
|
||||
->desc('Create user')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -203,10 +200,9 @@ App::post('/v1/users')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('plaintext', '{}', $userId, $email, $password, $phone, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('plaintext', '{}', $userId, $email, $password, $phone, $name, $project, $dbForProject, $hooks);
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($user, Response::MODEL_USER);
|
||||
|
|
@ -215,7 +211,6 @@ App::post('/v1/users')
|
|||
App::post('/v1/users/bcrypt')
|
||||
->desc('Create user with bcrypt password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -233,10 +228,9 @@ App::post('/v1/users/bcrypt')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('bcrypt', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('bcrypt', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -246,7 +240,6 @@ App::post('/v1/users/bcrypt')
|
|||
App::post('/v1/users/md5')
|
||||
->desc('Create user with MD5 password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -264,10 +257,9 @@ App::post('/v1/users/md5')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('md5', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('md5', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -277,7 +269,6 @@ App::post('/v1/users/md5')
|
|||
App::post('/v1/users/argon2')
|
||||
->desc('Create user with Argon2 password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -295,10 +286,9 @@ App::post('/v1/users/argon2')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('argon2', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('argon2', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -308,7 +298,6 @@ App::post('/v1/users/argon2')
|
|||
App::post('/v1/users/sha')
|
||||
->desc('Create user with SHA password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -327,16 +316,15 @@ App::post('/v1/users/sha')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$options = '{}';
|
||||
|
||||
if (!empty($passwordVersion)) {
|
||||
$options = '{"version":"' . $passwordVersion . '"}';
|
||||
}
|
||||
|
||||
$user = createUser('sha', $options, $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
$user = createUser('sha', $options, $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -346,7 +334,6 @@ App::post('/v1/users/sha')
|
|||
App::post('/v1/users/phpass')
|
||||
->desc('Create user with PHPass password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -364,10 +351,9 @@ App::post('/v1/users/phpass')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('phpass', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('phpass', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -377,7 +363,6 @@ App::post('/v1/users/phpass')
|
|||
App::post('/v1/users/scrypt')
|
||||
->desc('Create user with Scrypt password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -400,9 +385,8 @@ App::post('/v1/users/scrypt')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$options = [
|
||||
'salt' => $passwordSalt,
|
||||
'costCpu' => $passwordCpu,
|
||||
|
|
@ -411,7 +395,7 @@ App::post('/v1/users/scrypt')
|
|||
'length' => $passwordLength
|
||||
];
|
||||
|
||||
$user = createUser('scrypt', \json_encode($options), $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
$user = createUser('scrypt', \json_encode($options), $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
@ -421,7 +405,6 @@ App::post('/v1/users/scrypt')
|
|||
App::post('/v1/users/scrypt-modified')
|
||||
->desc('Create user with Scrypt modified password')
|
||||
->groups(['api', 'users'])
|
||||
->label('event', 'users.[userId].create')
|
||||
->label('scope', 'users.write')
|
||||
->label('audits.event', 'user.create')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
|
|
@ -442,10 +425,9 @@ App::post('/v1/users/scrypt-modified')
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('scryptMod', '{"signerKey":"' . $passwordSignerKey . '","saltSeparator":"' . $passwordSaltSeparator . '","salt":"' . $passwordSalt . '"}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$user = createUser('scryptMod', '{"signerKey":"' . $passwordSignerKey . '","saltSeparator":"' . $passwordSaltSeparator . '","salt":"' . $passwordSalt . '"}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ use Appwrite\Event\Delete;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Usage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Abuse\Abuse;
|
||||
|
|
@ -28,6 +29,7 @@ use Utopia\Database\DateTime;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Queue\Connection;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
|
|
@ -57,8 +59,36 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
|
|||
return $label;
|
||||
};
|
||||
|
||||
$databaseListener = function (string $event, Document $document, Document $project, Usage $queueForUsage, Database $dbForProject) {
|
||||
$eventDatabaseListener = function (Document $document, Response $response, Event $queueForEvents, Func $queueForFunctions, Webhook $queueForWebhooks, Realtime $queueForRealtime) {
|
||||
// Only trigger events for user creation with the database listener.
|
||||
if ($document->getCollection() !== 'users') {
|
||||
return;
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
->setEvent('users.[userId].create')
|
||||
->setParam('userId', $document->getId())
|
||||
->setPayload($response->output($document, Response::MODEL_USER));
|
||||
|
||||
// Trigger functions, webhooks, and realtime events
|
||||
$queueForFunctions
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
if ($queueForEvents->getProject()->getId() === 'console') {
|
||||
return;
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
};
|
||||
|
||||
$usageDatabaseListener = function (string $event, Document $document, Usage $queueForUsage) {
|
||||
$value = 1;
|
||||
if ($event === Database::EVENT_DOCUMENT_DELETE) {
|
||||
$value = -1;
|
||||
|
|
@ -353,6 +383,7 @@ App::init()
|
|||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('queue')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('queueForAudits')
|
||||
|
|
@ -362,7 +393,7 @@ App::init()
|
|||
->inject('queueForUsage')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($databaseListener) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Connection $queue, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
|
|
@ -456,9 +487,24 @@ App::init()
|
|||
$queueForBuilds->setProject($project);
|
||||
$queueForMessaging->setProject($project);
|
||||
|
||||
// Clone the queues, to prevent events triggered by the database listener
|
||||
// from overwriting the events that are supposed to be triggered in the shutdown hook.
|
||||
$queueForEventsClone = new Event($queue);
|
||||
$queueForFunctions = new Func($queue);
|
||||
$queueForWebhooks = new Webhook($queue);
|
||||
$queueForRealtime = new Realtime();
|
||||
|
||||
$dbForProject
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $databaseListener($event, $document, $project, $queueForUsage, $dbForProject))
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $databaseListener($event, $document, $project, $queueForUsage, $dbForProject));
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage))
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage))
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'create-trigger-events', fn ($event, $document) => $eventDatabaseListener(
|
||||
$document,
|
||||
$response,
|
||||
$queueForEventsClone->from($queueForEvents),
|
||||
$queueForFunctions->from($queueForEvents),
|
||||
$queueForWebhooks->from($queueForEvents),
|
||||
$queueForRealtime->from($queueForEvents)
|
||||
));
|
||||
|
||||
$useCache = $route->getLabel('cache', false);
|
||||
if ($useCache) {
|
||||
|
|
@ -591,11 +637,13 @@ App::shutdown()
|
|||
->inject('queueForDatabase')
|
||||
->inject('queueForBuilds')
|
||||
->inject('queueForMessaging')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForFunctions')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForRealtime')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
->inject('dbForConsole')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole) use ($parseLabel) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, string $mode, Database $dbForConsole) use ($parseLabel) {
|
||||
|
||||
$responsePayload = $response->getPayload();
|
||||
|
||||
|
|
@ -604,54 +652,18 @@ App::shutdown()
|
|||
$queueForEvents->setPayload($responsePayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger functions.
|
||||
*/
|
||||
if (!$queueForEvents->isPaused()) {
|
||||
$queueForFunctions
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
/**
|
||||
* Trigger webhooks.
|
||||
*/
|
||||
$queueForEvents
|
||||
->setClass(Event::WEBHOOK_CLASS_NAME)
|
||||
->setQueue(Event::WEBHOOK_QUEUE_NAME)
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
$queueForFunctions
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
/**
|
||||
* Trigger realtime.
|
||||
*/
|
||||
if ($project->getId() !== 'console') {
|
||||
$allEvents = Event::generateEvents($queueForEvents->getEvent(), $queueForEvents->getParams());
|
||||
$payload = new Document($queueForEvents->getPayload());
|
||||
|
||||
$db = $queueForEvents->getContext('database');
|
||||
$collection = $queueForEvents->getContext('collection');
|
||||
$bucket = $queueForEvents->getContext('bucket');
|
||||
|
||||
$target = Realtime::fromPayload(
|
||||
// Pass first, most verbose event pattern
|
||||
event: $allEvents[0],
|
||||
payload: $payload,
|
||||
project: $project,
|
||||
database: $db,
|
||||
collection: $collection,
|
||||
bucket: $bucket,
|
||||
);
|
||||
|
||||
Realtime::send(
|
||||
projectId: $target['projectId'] ?? $project->getId(),
|
||||
payload: $queueForEvents->getRealtimePayload(),
|
||||
events: $allEvents,
|
||||
channels: $target['channels'],
|
||||
roles: $target['roles'],
|
||||
options: [
|
||||
'permissionsChanged' => $target['permissionsChanged'],
|
||||
'userId' => $queueForEvents->getParam('userId')
|
||||
]
|
||||
);
|
||||
$queueForRealtime
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ use Appwrite\Event\Func;
|
|||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Usage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Functions\Specification;
|
||||
use Appwrite\GraphQL\Promises\Adapter\Swoole;
|
||||
|
|
@ -1134,6 +1136,12 @@ App::setResource('queueForDeletes', function (Connection $queue) {
|
|||
App::setResource('queueForEvents', function (Connection $queue) {
|
||||
return new Event($queue);
|
||||
}, ['queue']);
|
||||
App::setResource('queueForWebhooks', function (Connection $queue) {
|
||||
return new Webhook($queue);
|
||||
}, ['queue']);
|
||||
App::setResource('queueForRealtime', function () {
|
||||
return new Realtime();
|
||||
}, []);
|
||||
App::setResource('queueForAudits', function (Connection $queue) {
|
||||
return new Audit($queue);
|
||||
}, ['queue']);
|
||||
|
|
|
|||
|
|
@ -204,19 +204,6 @@ class Event
|
|||
return $this->payload;
|
||||
}
|
||||
|
||||
public function getRealtimePayload(): array
|
||||
{
|
||||
$payload = [];
|
||||
|
||||
foreach ($this->payload as $key => $value) {
|
||||
if (!isset($this->sensitive[$key])) {
|
||||
$payload[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set context for this event.
|
||||
*
|
||||
|
|
@ -315,10 +302,6 @@ class Event
|
|||
*/
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
|
|
@ -530,20 +513,21 @@ class Event
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the value of paused
|
||||
* Generate a function event from a base event
|
||||
*
|
||||
* @param Event $event
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
*/
|
||||
public function isPaused(): bool
|
||||
public function from(Event $event): self
|
||||
{
|
||||
return $this->paused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of paused
|
||||
*/
|
||||
public function setPaused(bool $paused): self
|
||||
{
|
||||
$this->paused = $paused;
|
||||
|
||||
$this->project = $event->getProject();
|
||||
$this->user = $event->getUser();
|
||||
$this->payload = $event->getPayload();
|
||||
$this->event = $event->getEvent();
|
||||
$this->params = $event->getParams();
|
||||
$this->context = $event->context;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,10 +213,6 @@ class Func extends Event
|
|||
*/
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
$events = $this->getEvent() ? Event::generateEvents($this->getEvent(), $this->getParams()) : null;
|
||||
|
|
@ -238,22 +234,4 @@ class Func extends Event
|
|||
'method' => $this->method,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a function event from a base event
|
||||
*
|
||||
* @param Event $event
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
*/
|
||||
public function from(Event $event): self
|
||||
{
|
||||
$this->project = $event->getProject();
|
||||
$this->user = $event->getUser();
|
||||
$this->payload = $event->getPayload();
|
||||
$this->event = $event->getEvent();
|
||||
$this->params = $event->getParams();
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
70
src/Appwrite/Event/Realtime.php
Normal file
70
src/Appwrite/Event/Realtime.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Appwrite\Messaging\Adapter\Realtime as RealtimeAdapter;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Realtime extends Event
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function getRealtimePayload(): array
|
||||
{
|
||||
$payload = [];
|
||||
|
||||
foreach ($this->payload as $key => $value) {
|
||||
if (!isset($this->sensitive[$key])) {
|
||||
$payload[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Event.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
if (empty($this->event)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$allEvents = Event::generateEvents($this->getEvent(), $this->getParams());
|
||||
$payload = new Document($this->getPayload());
|
||||
|
||||
$db = $this->getContext('database');
|
||||
$collection = $this->getContext('collection');
|
||||
$bucket = $this->getContext('bucket');
|
||||
|
||||
$target = RealtimeAdapter::fromPayload(
|
||||
// Pass first, most verbose event pattern
|
||||
event: $allEvents[0],
|
||||
payload: $payload,
|
||||
project: $this->getProject(),
|
||||
database: $db,
|
||||
collection: $collection,
|
||||
bucket: $bucket,
|
||||
);
|
||||
|
||||
RealtimeAdapter::send(
|
||||
projectId: $target['projectId'] ?? $this->getProject()->getId(),
|
||||
payload: $this->getRealtimePayload(),
|
||||
events: $allEvents,
|
||||
channels: $target['channels'],
|
||||
roles: $target['roles'],
|
||||
options: [
|
||||
'permissionsChanged' => $target['permissionsChanged'],
|
||||
'userId' => $this->getParam('userId')
|
||||
]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
17
src/Appwrite/Event/Webhook.php
Normal file
17
src/Appwrite/Event/Webhook.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Webhook extends Event
|
||||
{
|
||||
public function __construct(protected Connection $connection)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
|
||||
$this
|
||||
->setQueue(Event::WEBHOOK_QUEUE_NAME)
|
||||
->setClass(Event::WEBHOOK_CLASS_NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -901,6 +901,17 @@ trait WebhooksBase
|
|||
$teamId = $data['teamId'] ?? '';
|
||||
$email = uniqid() . 'friend@localhost.test';
|
||||
|
||||
// Create user to ensure team event is triggered after user event
|
||||
$user = $this->client->call(Client::METHOD_POST, '/account', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'userId' => ID::unique(),
|
||||
'email' => $email,
|
||||
'password' => 'password',
|
||||
'name' => 'Friend User',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
|
|
@ -909,7 +920,6 @@ trait WebhooksBase
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'email' => $email,
|
||||
'name' => 'Friend User',
|
||||
'roles' => ['admin', 'editor'],
|
||||
'url' => 'http://localhost:5000/join-us#title'
|
||||
]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue