mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.9.x' into feat-insights-module
This commit is contained in:
@@ -406,7 +406,7 @@ jobs:
|
||||
|
||||
e2e_service:
|
||||
name: Tests / E2E / ${{ matrix.database }} (${{ matrix.mode }}) / ${{ matrix.service }}
|
||||
runs-on: ${{ matrix.runner || 'ubuntu-latest' }}
|
||||
runs-on: ${{ matrix.runner || format('runs-on={0}/runner=4cpu-linux-x64/volume=120g/spot=false', github.run_id) }}
|
||||
needs: [build, matrix]
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -446,19 +446,10 @@ jobs:
|
||||
]
|
||||
include:
|
||||
- service: Databases
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
runner: runs-on=${{ github.run_id }}/runner=8cpu-linux-x64/volume=120g/spot=false
|
||||
paratest_processes: 3
|
||||
timeout_minutes: 30
|
||||
- service: Sites
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
- service: Functions
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
- service: Avatars
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
- service: Realtime
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
- service: TablesDB
|
||||
runner: runs-on=${{ github.run_id }}/runner=4cpu-linux-x64/family=c7/volume=120g
|
||||
paratest_processes: 3
|
||||
timeout_minutes: 30
|
||||
- service: Migrations
|
||||
|
||||
+1
-1
@@ -323,7 +323,7 @@ return [
|
||||
[
|
||||
'key' => 'codex-plugin',
|
||||
'name' => 'CodexPlugin',
|
||||
'version' => '0.1.0',
|
||||
'version' => '0.1.1',
|
||||
'url' => 'https://github.com/appwrite/codex-plugin.git',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
|
||||
@@ -1336,6 +1336,15 @@ return [
|
||||
'category' => 'Migrations',
|
||||
'description' => '',
|
||||
'variables' => [
|
||||
[
|
||||
'name' => '_APP_MIGRATION_HOST',
|
||||
'description' => 'Internal hostname the migrations worker uses to reach this instance\'s API (for migrations and CSV/JSON imports & exports). Defaults to \'appwrite\', the API service name in the standard Docker Compose setup. Only change this for non-standard deployments.',
|
||||
'introduction' => '1.9.0',
|
||||
'default' => 'appwrite',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_MIGRATIONS_FIREBASE_CLIENT_ID',
|
||||
'description' => 'Google OAuth client ID. You can find it in your GCP application settings.',
|
||||
|
||||
+126
-125
@@ -13,8 +13,10 @@ use Appwrite\Bus\Events\SessionCreated;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Hooks\Hooks;
|
||||
use Appwrite\Network\Validator\Redirect;
|
||||
@@ -2113,12 +2115,12 @@ Http::post('/v1/account/tokens/magic-url')
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('plan')
|
||||
->inject('proofForPassword')
|
||||
->inject('platform')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, array $plan, ProofsPassword $proofForPassword, array $platform, Authorization $authorization) {
|
||||
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, MailPublisher $publisherForMails, array $plan, ProofsPassword $proofForPassword, array $platform, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
|
||||
}
|
||||
@@ -2304,6 +2306,7 @@ Http::post('/v1/account/tokens/magic-url')
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
@@ -2321,13 +2324,6 @@ Http::post('/v1/account/tokens/magic-url')
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -2348,11 +2344,17 @@ Http::post('/v1/account/tokens/magic-url')
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$projectName = $project->getAttribute('name');
|
||||
@@ -2374,18 +2376,17 @@ Http::post('/v1/account/tokens/magic-url')
|
||||
'team' => '',
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->appendVariables($emailVariables)
|
||||
->setRecipient($email);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $email,
|
||||
subject: $subject,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $project->getId() === 'console' ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$token->setAttribute('secret', $tokenSecret);
|
||||
|
||||
@@ -2436,12 +2437,12 @@ Http::post('/v1/account/tokens/email')
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('plan')
|
||||
->inject('proofForPassword')
|
||||
->inject('proofForCode')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, User $user, Document $project, array $platform, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, array $plan, ProofsPassword $proofForPassword, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, User $user, Document $project, array $platform, Database $dbForProject, Locale $locale, Event $queueForEvents, MailPublisher $publisherForMails, array $plan, ProofsPassword $proofForPassword, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
|
||||
}
|
||||
@@ -2633,6 +2634,7 @@ Http::post('/v1/account/tokens/email')
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
@@ -2650,13 +2652,6 @@ Http::post('/v1/account/tokens/email')
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -2677,11 +2672,17 @@ Http::post('/v1/account/tokens/email')
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$projectName = $project->getAttribute('name');
|
||||
@@ -2717,20 +2718,18 @@ Http::post('/v1/account/tokens/email')
|
||||
]);
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setBodyTemplate($bodyTemplate)
|
||||
->appendVariables($emailVariables)
|
||||
->setRecipient($email);
|
||||
|
||||
// since this is console project, set email sender name!
|
||||
if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $email,
|
||||
subject: $subject,
|
||||
bodyTemplate: $bodyTemplate,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$token->setAttribute('secret', $tokenSecret);
|
||||
|
||||
@@ -2880,7 +2879,7 @@ Http::post('/v1/account/tokens/phone')
|
||||
->inject('platform')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('locale')
|
||||
->inject('timelimit')
|
||||
->inject('usage')
|
||||
@@ -2888,7 +2887,7 @@ Http::post('/v1/account/tokens/phone')
|
||||
->inject('store')
|
||||
->inject('proofForCode')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $phone, Request $request, Response $response, User $user, Document $project, array $platform, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale, callable $timelimit, Context $usage, array $plan, Store $store, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
->action(function (string $userId, string $phone, Request $request, Response $response, User $user, Document $project, array $platform, Database $dbForProject, Event $queueForEvents, MessagingPublisher $publisherForMessaging, Locale $locale, callable $timelimit, Context $usage, array $plan, Store $store, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
}
|
||||
@@ -3021,11 +3020,13 @@ Http::post('/v1/account/tokens/phone')
|
||||
],
|
||||
]);
|
||||
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
||||
->setMessage($messageDoc)
|
||||
->setRecipients([$phone])
|
||||
->setProviderType(MESSAGE_TYPE_SMS);
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_INTERNAL,
|
||||
project: $project,
|
||||
message: $messageDoc,
|
||||
recipients: [$phone],
|
||||
providerType: MESSAGE_TYPE_SMS,
|
||||
));
|
||||
|
||||
$helper = PhoneNumberUtil::getInstance();
|
||||
try {
|
||||
@@ -3681,11 +3682,11 @@ Http::post('/v1/account/recovery')
|
||||
->inject('project')
|
||||
->inject('platform')
|
||||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('queueForEvents')
|
||||
->inject('proofForToken')
|
||||
->inject('authorization')
|
||||
->action(function (string $email, string $url, Request $request, Response $response, User $user, Database $dbForProject, Document $project, array $platform, Locale $locale, Mail $queueForMails, Event $queueForEvents, ProofsToken $proofForToken, Authorization $authorization) {
|
||||
->action(function (string $email, string $url, Request $request, Response $response, User $user, Database $dbForProject, Document $project, array $platform, Locale $locale, MailPublisher $publisherForMails, Event $queueForEvents, ProofsToken $proofForToken, Authorization $authorization) {
|
||||
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
|
||||
@@ -3768,6 +3769,7 @@ Http::post('/v1/account/recovery')
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
@@ -3785,13 +3787,6 @@ Http::post('/v1/account/recovery')
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -3812,11 +3807,17 @@ Http::post('/v1/account/recovery')
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
@@ -3829,19 +3830,18 @@ Http::post('/v1/account/recovery')
|
||||
'team' => ''
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setRecipient($profile->getAttribute('email', ''))
|
||||
->setName($profile->getAttribute('name', ''))
|
||||
->setBody($body)
|
||||
->appendVariables($emailVariables)
|
||||
->setSubject($subject)
|
||||
->setPreview($preview);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $profile->getAttribute('email', ''),
|
||||
name: $profile->getAttribute('name', ''),
|
||||
subject: $subject,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $project->getId() === 'console' ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$recovery->setAttribute('secret', $secret);
|
||||
|
||||
@@ -4009,10 +4009,10 @@ Http::post('/v1/account/verifications/email')
|
||||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('proofForToken')
|
||||
->inject('authorization')
|
||||
->action(function (string $url, Request $request, Response $response, Document $project, array $platform, User $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails, ProofsToken $proofForToken, Authorization $authorization) {
|
||||
->action(function (string $url, Request $request, Response $response, Document $project, array $platform, User $user, Database $dbForProject, Locale $locale, Event $queueForEvents, MailPublisher $publisherForMails, ProofsToken $proofForToken, Authorization $authorization) {
|
||||
|
||||
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
|
||||
@@ -4099,6 +4099,7 @@ Http::post('/v1/account/verifications/email')
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
@@ -4116,13 +4117,6 @@ Http::post('/v1/account/verifications/email')
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -4143,11 +4137,17 @@ Http::post('/v1/account/verifications/email')
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
@@ -4174,20 +4174,19 @@ Http::post('/v1/account/verifications/email')
|
||||
]);
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setBodyTemplate($bodyTemplate)
|
||||
->appendVariables($emailVariables)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setName($user->getAttribute('name') ?? '');
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $user->getAttribute('email'),
|
||||
name: $user->getAttribute('name') ?? '',
|
||||
subject: $subject,
|
||||
bodyTemplate: $bodyTemplate,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $project->getId() === 'console' ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$verification->setAttribute('secret', $verificationSecret);
|
||||
|
||||
@@ -4321,7 +4320,7 @@ Http::post('/v1/account/verifications/phone')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('timelimit')
|
||||
@@ -4329,7 +4328,7 @@ Http::post('/v1/account/verifications/phone')
|
||||
->inject('plan')
|
||||
->inject('proofForCode')
|
||||
->inject('authorization')
|
||||
->action(function (Request $request, Response $response, User $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale, callable $timelimit, Context $usage, array $plan, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
->action(function (Request $request, Response $response, User $user, Database $dbForProject, Event $queueForEvents, MessagingPublisher $publisherForMessaging, Document $project, Locale $locale, callable $timelimit, Context $usage, array $plan, ProofsCode $proofForCode, Authorization $authorization) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
}
|
||||
@@ -4398,11 +4397,13 @@ Http::post('/v1/account/verifications/phone')
|
||||
],
|
||||
]);
|
||||
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
||||
->setMessage($messageDoc)
|
||||
->setRecipients([$user->getAttribute('phone')])
|
||||
->setProviderType(MESSAGE_TYPE_SMS);
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_INTERNAL,
|
||||
project: $project,
|
||||
message: $messageDoc,
|
||||
recipients: [$user->getAttribute('phone')],
|
||||
providerType: MESSAGE_TYPE_SMS,
|
||||
));
|
||||
|
||||
$helper = PhoneNumberUtil::getInstance();
|
||||
try {
|
||||
|
||||
@@ -5,7 +5,8 @@ use Appwrite\Auth\Validator\Phone;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Messaging\Status as MessageStatus;
|
||||
use Appwrite\Permission;
|
||||
@@ -3187,9 +3188,9 @@ Http::post('/v1/messaging/messages/email')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, string $subject, string $content, ?array $topics, ?array $users, ?array $targets, ?array $cc, ?array $bcc, ?array $attachments, bool $draft, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, string $subject, string $content, ?array $topics, ?array $users, ?array $targets, ?array $cc, ?array $bcc, ?array $attachments, bool $draft, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -3274,9 +3275,11 @@ Http::post('/v1/messaging/messages/email')
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
@@ -3362,9 +3365,9 @@ Http::post('/v1/messaging/messages/sms')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, string $content, ?array $topics, ?array $users, ?array $targets, bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, string $content, ?array $topics, ?array $users, ?array $targets, bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -3418,9 +3421,11 @@ Http::post('/v1/messaging/messages/sms')
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
@@ -3498,10 +3503,10 @@ Http::post('/v1/messaging/messages/push')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->inject('platform')
|
||||
->action(function (string $messageId, string $title, string $body, ?array $topics, ?array $users, ?array $targets, ?array $data, string $action, string $image, string $icon, string $sound, string $color, string $tag, int $badge, bool $draft, ?string $scheduledAt, bool $contentAvailable, bool $critical, string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response, array $platform) {
|
||||
->action(function (string $messageId, string $title, string $body, ?array $topics, ?array $users, ?array $targets, ?array $data, string $action, string $image, string $icon, string $sound, string $color, string $tag, int $badge, bool $draft, ?string $scheduledAt, bool $contentAvailable, bool $critical, string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response, array $platform) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -3638,9 +3643,11 @@ Http::post('/v1/messaging/messages/push')
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
@@ -3983,9 +3990,9 @@ Http::patch('/v1/messaging/messages/email/:messageId')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $subject, ?string $content, ?bool $draft, ?bool $html, ?array $cc, ?array $bcc, ?string $scheduledAt, ?array $attachments, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $subject, ?string $content, ?bool $draft, ?bool $html, ?array $cc, ?array $bcc, ?string $scheduledAt, ?array $attachments, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -4141,9 +4148,11 @@ Http::patch('/v1/messaging/messages/email/:messageId')
|
||||
$message = $dbForProject->updateDocument('messages', $message->getId(), $message);
|
||||
|
||||
if ($status === MessageStatus::PROCESSING) {
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
@@ -4205,9 +4214,9 @@ Http::patch('/v1/messaging/messages/sms/:messageId')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $content, ?bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $content, ?bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -4323,9 +4332,11 @@ Http::patch('/v1/messaging/messages/sms/:messageId')
|
||||
$message = $dbForProject->updateDocument('messages', $message->getId(), $message);
|
||||
|
||||
if ($status === MessageStatus::PROCESSING) {
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
@@ -4379,10 +4390,10 @@ Http::patch('/v1/messaging/messages/push/:messageId')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->inject('platform')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $title, ?string $body, ?array $data, ?string $action, ?string $image, ?string $icon, ?string $sound, ?string $color, ?string $tag, ?int $badge, ?bool $draft, ?string $scheduledAt, ?bool $contentAvailable, ?bool $critical, ?string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response, array $platform) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $title, ?string $body, ?array $data, ?string $action, ?string $image, ?string $icon, ?string $sound, ?string $color, ?string $tag, ?int $badge, ?bool $draft, ?string $scheduledAt, ?bool $contentAvailable, ?bool $critical, ?string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, MessagingPublisher $publisherForMessaging, Response $response, array $platform) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -4584,9 +4595,11 @@ Http::patch('/v1/messaging/messages/push/:messageId')
|
||||
$message = $dbForProject->updateDocument('messages', $message->getId(), $message);
|
||||
|
||||
if ($status === MessageStatus::PROCESSING) {
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($message->getId());
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $project,
|
||||
messageId: $message->getId(),
|
||||
));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
use Appwrite\Auth\Validator\MockNumber;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
@@ -27,37 +24,6 @@ Http::init()
|
||||
}
|
||||
});
|
||||
|
||||
Http::get('/v1/projects/:projectId')
|
||||
->desc('Get project')
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'projects.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'projects',
|
||||
group: 'projects',
|
||||
name: 'get',
|
||||
description: '/docs/references/projects/get.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->action(function (string $projectId, Response $response, Database $dbForPlatform) {
|
||||
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
});
|
||||
|
||||
// Backwards compatibility
|
||||
Http::patch('/v1/projects/:projectId/oauth2')
|
||||
->desc('Update project OAuth2')
|
||||
|
||||
@@ -29,6 +29,7 @@ use Appwrite\Utopia\Request\Filters\V22 as RequestV22;
|
||||
use Appwrite\Utopia\Request\Filters\V23 as RequestV23;
|
||||
use Appwrite\Utopia\Request\Filters\V24 as RequestV24;
|
||||
use Appwrite\Utopia\Request\Filters\V25 as RequestV25;
|
||||
use Appwrite\Utopia\Request\Filters\V26 as RequestV26;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Filters\V16 as ResponseV16;
|
||||
use Appwrite\Utopia\Response\Filters\V17 as ResponseV17;
|
||||
@@ -40,6 +41,7 @@ use Appwrite\Utopia\Response\Filters\V22 as ResponseV22;
|
||||
use Appwrite\Utopia\Response\Filters\V23 as ResponseV23;
|
||||
use Appwrite\Utopia\Response\Filters\V24 as ResponseV24;
|
||||
use Appwrite\Utopia\Response\Filters\V25 as ResponseV25;
|
||||
use Appwrite\Utopia\Response\Filters\V26 as ResponseV26;
|
||||
use Appwrite\Utopia\View;
|
||||
use Executor\Exception\Timeout as ExecutorTimeout;
|
||||
use Executor\Executor;
|
||||
@@ -914,6 +916,9 @@ Http::init()
|
||||
if (version_compare($requestFormat, '1.9.4', '<')) {
|
||||
$request->addFilter(new RequestV25());
|
||||
}
|
||||
if (version_compare($requestFormat, '1.9.5', '<')) {
|
||||
$request->addFilter(new RequestV26());
|
||||
}
|
||||
}
|
||||
|
||||
$localeParam = (string) $request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
|
||||
@@ -938,6 +943,9 @@ Http::init()
|
||||
*/
|
||||
$responseFormat = $request->getHeader('x-appwrite-response-format', System::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($responseFormat) {
|
||||
if (version_compare($responseFormat, '1.9.5', '<')) {
|
||||
$response->addFilter(new ResponseV26());
|
||||
}
|
||||
if (version_compare($responseFormat, '1.9.4', '<')) {
|
||||
$response->addFilter(new ResponseV25());
|
||||
}
|
||||
|
||||
@@ -8,10 +8,8 @@ use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Audit as AuditMessage;
|
||||
use Appwrite\Event\Message\Usage as UsageMessage;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Publisher\Audit;
|
||||
use Appwrite\Event\Publisher\Usage as UsagePublisher;
|
||||
use Appwrite\Event\Realtime;
|
||||
@@ -486,13 +484,11 @@ Http::init()
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('auditContext')
|
||||
->inject('queueForDeletes')
|
||||
->inject('queueForDatabase')
|
||||
->inject('usage')
|
||||
->inject('queueForFunctions')
|
||||
->inject('queueForMails')
|
||||
->inject('dbForProject')
|
||||
->inject('timelimit')
|
||||
->inject('resourceToken')
|
||||
@@ -504,7 +500,7 @@ Http::init()
|
||||
->inject('platform')
|
||||
->inject('authorization')
|
||||
->inject('cacheControlForStorage')
|
||||
->action(function (Http $utopia, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, Messaging $queueForMessaging, AuditContext $auditContext, Delete $queueForDeletes, EventDatabase $queueForDatabase, Context $usage, Func $queueForFunctions, Mail $queueForMails, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, array $platform, Authorization $authorization, callable $cacheControlForStorage) {
|
||||
->action(function (Http $utopia, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, AuditContext $auditContext, Delete $queueForDeletes, EventDatabase $queueForDatabase, Context $usage, Func $queueForFunctions, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, array $platform, Authorization $authorization, callable $cacheControlForStorage) {
|
||||
|
||||
$response->setUser($user);
|
||||
$request->setUser($user);
|
||||
@@ -617,13 +613,10 @@ Http::init()
|
||||
/* Auto-set projects */
|
||||
$queueForDeletes->setProject($project);
|
||||
$queueForDatabase->setProject($project);
|
||||
$queueForMessaging->setProject($project);
|
||||
$queueForFunctions->setProject($project);
|
||||
$queueForMails->setProject($project);
|
||||
|
||||
/* Auto-set platforms */
|
||||
$queueForFunctions->setPlatform($platform);
|
||||
$queueForMails->setPlatform($platform);
|
||||
|
||||
$useCache = $route->getLabel('cache', false);
|
||||
$storageCacheOperationsCounter = $telemetry->createCounter('storage.cache.operations.load');
|
||||
@@ -815,7 +808,6 @@ Http::shutdown()
|
||||
->inject('publisherForUsage')
|
||||
->inject('queueForDeletes')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForMessaging')
|
||||
->inject('queueForFunctions')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForRealtime')
|
||||
@@ -826,7 +818,7 @@ Http::shutdown()
|
||||
->inject('bus')
|
||||
->inject('apiKey')
|
||||
->inject('mode')
|
||||
->action(function (Http $utopia, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, AuditContext $auditContext, Audit $publisherForAudits, Context $usage, UsagePublisher $publisherForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization, callable $timelimit, EventProcessor $eventProcessor, Bus $bus, ?Key $apiKey, string $mode) use ($parseLabel) {
|
||||
->action(function (Http $utopia, Request $request, Response $response, Document $project, User $user, Event $queueForEvents, AuditContext $auditContext, Audit $publisherForAudits, Context $usage, UsagePublisher $publisherForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization, callable $timelimit, EventProcessor $eventProcessor, Bus $bus, ?Key $apiKey, string $mode) use ($parseLabel) {
|
||||
|
||||
$responsePayload = $response->getPayload();
|
||||
|
||||
@@ -975,10 +967,6 @@ Http::shutdown()
|
||||
$queueForDatabase->trigger();
|
||||
}
|
||||
|
||||
if (! empty($queueForMessaging->getType())) {
|
||||
$queueForMessaging->trigger();
|
||||
}
|
||||
|
||||
// Cache label
|
||||
$useCache = $route->getLabel('cache', false);
|
||||
if ($useCache) {
|
||||
|
||||
@@ -50,8 +50,8 @@ const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_RESOURCE_TOKEN_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 4327;
|
||||
const APP_VERSION_STABLE = '1.9.4';
|
||||
const APP_CACHE_BUSTER = 4325;
|
||||
const APP_VERSION_STABLE = '1.9.5';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
|
||||
|
||||
@@ -175,6 +175,9 @@ use Appwrite\Utopia\Response\Model\PolicySessionLimit;
|
||||
use Appwrite\Utopia\Response\Model\PolicyUserLimit;
|
||||
use Appwrite\Utopia\Response\Model\Preferences;
|
||||
use Appwrite\Utopia\Response\Model\Project;
|
||||
use Appwrite\Utopia\Response\Model\ProjectAuthMethod;
|
||||
use Appwrite\Utopia\Response\Model\ProjectProtocol;
|
||||
use Appwrite\Utopia\Response\Model\ProjectService;
|
||||
use Appwrite\Utopia\Response\Model\Provider;
|
||||
use Appwrite\Utopia\Response\Model\ProviderRepository;
|
||||
use Appwrite\Utopia\Response\Model\ProviderRepositoryFramework;
|
||||
@@ -402,6 +405,9 @@ Response::setModel(new FrameworkAdapter());
|
||||
Response::setModel(new Deployment());
|
||||
Response::setModel(new Execution());
|
||||
Response::setModel(new Project());
|
||||
Response::setModel(new ProjectAuthMethod());
|
||||
Response::setModel(new ProjectService());
|
||||
Response::setModel(new ProjectProtocol());
|
||||
Response::setModel(new Webhook());
|
||||
Response::setModel(new Key());
|
||||
Response::setModel(new EphemeralKey());
|
||||
|
||||
@@ -5,6 +5,8 @@ use Appwrite\Event\Publisher\Audit as AuditPublisher;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Event\Publisher\Certificate as CertificatePublisher;
|
||||
use Appwrite\Event\Publisher\Execution as ExecutionPublisher;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Event\Publisher\Migration as MigrationPublisher;
|
||||
use Appwrite\Event\Publisher\Screenshot as ScreenshotPublisher;
|
||||
use Appwrite\Event\Publisher\StatsResources as StatsResourcesPublisher;
|
||||
@@ -118,6 +120,14 @@ $container->set('publisherForBuilds', fn (Publisher $publisher) => new BuildPubl
|
||||
$publisher,
|
||||
new Queue(System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME))
|
||||
), ['publisher']);
|
||||
$container->set('publisherForMails', fn (Publisher $publisher) => new MailPublisher(
|
||||
$publisher,
|
||||
new Queue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME))
|
||||
), ['publisher']);
|
||||
$container->set('publisherForMessaging', fn (Publisher $publisher) => new MessagingPublisher(
|
||||
$publisher,
|
||||
new Queue(System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME))
|
||||
), ['publisher']);
|
||||
|
||||
/**
|
||||
* Platform configuration
|
||||
|
||||
@@ -9,8 +9,6 @@ use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
@@ -116,12 +114,6 @@ return function (Container $container): void {
|
||||
});
|
||||
|
||||
// Per-request queue resources (stateful, accumulate event data during request)
|
||||
$container->set('queueForMessaging', function (Publisher $publisher) {
|
||||
return new Messaging($publisher);
|
||||
}, ['publisher']);
|
||||
$container->set('queueForMails', function (Publisher $publisher) {
|
||||
return new Mail($publisher);
|
||||
}, ['publisher']);
|
||||
$container->set('queueForDatabase', function (Publisher $publisher) {
|
||||
return new EventDatabase($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
@@ -4,8 +4,6 @@ use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Usage\Context;
|
||||
@@ -333,14 +331,6 @@ return function (Container $container): void {
|
||||
return new EventDatabase($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
$container->set('queueForMessaging', function (Publisher $publisher) {
|
||||
return new Messaging($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
$container->set('queueForMails', function (Publisher $publisher) {
|
||||
return new Mail($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
$container->set('queueForDeletes', function (Publisher $publisher) {
|
||||
return new Delete($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
Generated
+12
-12
@@ -3614,16 +3614,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/cache.git",
|
||||
"reference": "d36f9050c39c02e09a7763389c9e71258e74af1f"
|
||||
"reference": "ef52a04e8bfa314c621e3d3326ffcf50db3dfdfa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/d36f9050c39c02e09a7763389c9e71258e74af1f",
|
||||
"reference": "d36f9050c39c02e09a7763389c9e71258e74af1f",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/ef52a04e8bfa314c621e3d3326ffcf50db3dfdfa",
|
||||
"reference": "ef52a04e8bfa314c621e3d3326ffcf50db3dfdfa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3660,9 +3660,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/cache/issues",
|
||||
"source": "https://github.com/utopia-php/cache/tree/1.0.2"
|
||||
"source": "https://github.com/utopia-php/cache/tree/1.0.3"
|
||||
},
|
||||
"time": "2026-05-08T11:40:20+00:00"
|
||||
"time": "2026-05-11T11:02:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cli",
|
||||
@@ -5476,16 +5476,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "1.28.1",
|
||||
"version": "1.28.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "009118ccda8ccece2b9fc043c158cb1dd3efaa88"
|
||||
"reference": "38de925e8c9e7f0f720d45187be54a291aaf696b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/009118ccda8ccece2b9fc043c158cb1dd3efaa88",
|
||||
"reference": "009118ccda8ccece2b9fc043c158cb1dd3efaa88",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/38de925e8c9e7f0f720d45187be54a291aaf696b",
|
||||
"reference": "38de925e8c9e7f0f720d45187be54a291aaf696b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5521,9 +5521,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.28.1"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.28.4"
|
||||
},
|
||||
"time": "2026-05-08T13:24:33+00:00"
|
||||
"time": "2026-05-11T13:55:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brianium/paratest",
|
||||
|
||||
+1
-1
@@ -255,7 +255,7 @@ services:
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: appwrite/console:7.8.45
|
||||
image: appwrite/console:8
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
@@ -4,14 +4,14 @@ namespace Appwrite\Bus\Listeners;
|
||||
|
||||
use Appwrite\Auth\MFA\Type;
|
||||
use Appwrite\Bus\Events\SessionCreated;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Template\Template;
|
||||
use Utopia\Bus\Listener;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Storage\Validator\FileName;
|
||||
use Utopia\System\System;
|
||||
|
||||
@@ -31,14 +31,14 @@ class Mails extends Listener
|
||||
{
|
||||
$this
|
||||
->desc('Sends session alert emails')
|
||||
->inject('publisher')
|
||||
->inject('publisherForMails')
|
||||
->inject('locale')
|
||||
->inject('platform')
|
||||
->inject('dbForProject')
|
||||
->callback($this->handle(...));
|
||||
}
|
||||
|
||||
public function handle(SessionCreated $event, Publisher $publisher, Locale $locale, array $platform, Database $dbForProject): void
|
||||
public function handle(SessionCreated $event, MailPublisher $publisherForMails, Locale $locale, array $platform, Database $dbForProject): void
|
||||
{
|
||||
$project = new Document($event->project);
|
||||
|
||||
@@ -124,34 +124,32 @@ class Mails extends Listener
|
||||
];
|
||||
}
|
||||
|
||||
$queueForMails = new Mail($publisher);
|
||||
|
||||
$smtpConfig = [];
|
||||
if ($smtp['enabled'] ?? false) {
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '')
|
||||
->setSmtpReplyToEmail($customTemplate['replyToEmail'] ?? $customTemplate['replyTo'] ?? $smtp['replyToEmail'] ?? $smtp['replyTo'] ?? '') // Includes backwards compatibility
|
||||
->setSmtpReplyToName($customTemplate['replyToName'] ?? $smtp['replyToName'] ?? '')
|
||||
->setSmtpSenderEmail($customTemplate['senderEmail'] ?? $smtp['senderEmail'] ?? System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM))
|
||||
->setSmtpSenderName($customTemplate['senderName'] ?? $smtp['senderName'] ?? System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $customTemplate['replyToEmail'] ?? $customTemplate['replyTo'] ?? $smtp['replyToEmail'] ?? $smtp['replyTo'] ?? '', // Includes backwards compatibility
|
||||
'replyToName' => $customTemplate['replyToName'] ?? $smtp['replyToName'] ?? '',
|
||||
'senderEmail' => $customTemplate['senderEmail'] ?? $smtp['senderEmail'] ?? System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
'senderName' => $customTemplate['senderName'] ?? $smtp['senderName'] ?? System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'),
|
||||
];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setProject($project)
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setBodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/' . $smtpBaseTemplate . '.tpl')
|
||||
->appendVariables($emailVariables)
|
||||
->setRecipient($event->user['email']);
|
||||
|
||||
if ($isBranded) {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $event->user['email'],
|
||||
subject: $subject,
|
||||
bodyTemplate: __DIR__ . '/../../../../app/config/locale/templates/' . $smtpBaseTemplate . '.tpl',
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $isBranded ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,576 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\System\System;
|
||||
|
||||
class Mail extends Event
|
||||
{
|
||||
protected string $recipient = '';
|
||||
protected string $name = '';
|
||||
protected string $subject = '';
|
||||
protected string $body = '';
|
||||
protected string $preview = '';
|
||||
protected array $smtp = [];
|
||||
protected array $variables = [];
|
||||
protected string $bodyTemplate = '';
|
||||
protected array $attachment = [];
|
||||
|
||||
protected array $customMailOptions = [];
|
||||
|
||||
public function __construct(protected Publisher $publisher)
|
||||
{
|
||||
parent::__construct($publisher);
|
||||
|
||||
$this
|
||||
->setQueue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME))
|
||||
->setClass(System::getEnv('_APP_MAILS_CLASS_NAME', Event::MAILS_CLASS_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets subject for the mail event.
|
||||
*
|
||||
* @param string $subject
|
||||
* @return self
|
||||
*/
|
||||
public function setSubject(string $subject): self
|
||||
{
|
||||
$this->subject = $subject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subject for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSubject(): string
|
||||
{
|
||||
return $this->subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets recipient for the mail event.
|
||||
*
|
||||
* @param string $recipient
|
||||
* @return self
|
||||
*/
|
||||
public function setRecipient(string $recipient): self
|
||||
{
|
||||
$this->recipient = $recipient;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set recipient for mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRecipient(): string
|
||||
{
|
||||
return $this->recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets body for the mail event.
|
||||
*
|
||||
* @param string $body
|
||||
* @return self
|
||||
*/
|
||||
public function setBody(string $body): self
|
||||
{
|
||||
$this->body = $body;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns body for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBody(): string
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets preview for the mail event.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPreview(string $preview): self
|
||||
{
|
||||
$this->preview = $preview;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns preview for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPreview(): string
|
||||
{
|
||||
return $this->preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name for the mail event.
|
||||
*
|
||||
* @param string $name
|
||||
* @return self
|
||||
*/
|
||||
public function setName(string $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set name for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bodyTemplate for the mail event.
|
||||
*
|
||||
* @param string $bodyTemplate
|
||||
* @return self
|
||||
*/
|
||||
public function setBodyTemplate(string $bodyTemplate): self
|
||||
{
|
||||
$this->bodyTemplate = $bodyTemplate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns subject for the mail event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBodyTemplate(): string
|
||||
{
|
||||
return $this->bodyTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP Host
|
||||
*
|
||||
* @param string $host
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpHost(string $host): self
|
||||
{
|
||||
$this->smtp['host'] = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP port
|
||||
*
|
||||
* @param int $port
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpPort(int $port): self
|
||||
{
|
||||
$this->smtp['port'] = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP username
|
||||
*
|
||||
* @param string $username
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpUsername(string $username): self
|
||||
{
|
||||
$this->smtp['username'] = $username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP password
|
||||
*
|
||||
* @param string $password
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpPassword(string $password): self
|
||||
{
|
||||
$this->smtp['password'] = $password;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP secure
|
||||
*
|
||||
* @param string $secure
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpSecure(string $secure): self
|
||||
{
|
||||
$this->smtp['secure'] = $secure;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP sender email
|
||||
*
|
||||
* @param string $senderEmail
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpSenderEmail(string $senderEmail): self
|
||||
{
|
||||
$this->smtp['senderEmail'] = $senderEmail;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP sender name
|
||||
*
|
||||
* @param string $senderName
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpSenderName(string $senderName): self
|
||||
{
|
||||
$this->smtp['senderName'] = $senderName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP reply-to email
|
||||
*
|
||||
* @param string $email
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpReplyToEmail(string $email): self
|
||||
{
|
||||
$this->smtp['replyToEmail'] = $email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SMTP reply-to name
|
||||
*
|
||||
* @param string $name
|
||||
* @return self
|
||||
*/
|
||||
public function setSmtpReplyToName(string $name): self
|
||||
{
|
||||
$this->smtp['replyToName'] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpHost(): string
|
||||
{
|
||||
return $this->smtp['host'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP port
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getSmtpPort(): int
|
||||
{
|
||||
return $this->smtp['port'] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP username
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpUsername(): string
|
||||
{
|
||||
return $this->smtp['username'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP password
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpPassword(): string
|
||||
{
|
||||
return $this->smtp['password'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP secure
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSecure(): string
|
||||
{
|
||||
return $this->smtp['secure'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP sender email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSenderEmail(): string
|
||||
{
|
||||
return $this->smtp['senderEmail'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP sender name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpSenderName(): string
|
||||
{
|
||||
return $this->smtp['senderName'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP reply-to email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpReplyToEmail(): string
|
||||
{
|
||||
return $this->smtp['replyToEmail'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SMTP reply-to name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSmtpReplyToName(): string
|
||||
{
|
||||
return $this->smtp['replyToName'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Email Variables
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVariables(): array
|
||||
{
|
||||
return $this->variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Email Variables
|
||||
*
|
||||
* @param array $variables
|
||||
* @return self
|
||||
*/
|
||||
public function setVariables(array $variables): self
|
||||
{
|
||||
$this->variables = $variables;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append variables to the email event.
|
||||
*
|
||||
* @param array $variables
|
||||
* @return self
|
||||
*/
|
||||
public function appendVariables(array $variables): self
|
||||
{
|
||||
$this->variables = \array_merge($this->variables, $variables);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attachment
|
||||
* @param string $content
|
||||
* @param string $filename
|
||||
* @param string $encoding
|
||||
* @param string $type
|
||||
* @return self
|
||||
*/
|
||||
public function setAttachment(string $content, string $filename, string $encoding = 'base64', string $type = 'plain/text')
|
||||
{
|
||||
$this->attachment = [
|
||||
'content' => base64_encode($content),
|
||||
'filename' => $filename,
|
||||
'encoding' => $encoding,
|
||||
'type' => $type,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttachment(): array
|
||||
{
|
||||
return $this->attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset attachment
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function resetAttachment(): self
|
||||
{
|
||||
$this->attachment = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sender email
|
||||
*
|
||||
* @param string $email
|
||||
* @return self
|
||||
*/
|
||||
public function setSenderEmail(string $email): self
|
||||
{
|
||||
$this->customMailOptions['senderEmail'] = $email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sender email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderEmail(): string
|
||||
{
|
||||
return $this->customMailOptions['senderEmail'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sender name
|
||||
*
|
||||
* @param string $name
|
||||
* @return self
|
||||
*/
|
||||
public function setSenderName(string $name): self
|
||||
{
|
||||
$this->customMailOptions['senderName'] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sender name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderName(): string
|
||||
{
|
||||
return $this->customMailOptions['senderName'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set reply-to email
|
||||
*
|
||||
* @param string $email
|
||||
* @return self
|
||||
*/
|
||||
public function setReplyToEmail(string $email): self
|
||||
{
|
||||
$this->customMailOptions['replyToEmail'] = $email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reply-to email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReplyToEmail(): string
|
||||
{
|
||||
return $this->customMailOptions['replyToEmail'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set reply-to name
|
||||
*
|
||||
* @param string $name
|
||||
* @return self
|
||||
*/
|
||||
public function setReplyToName(string $name): self
|
||||
{
|
||||
$this->customMailOptions['replyToName'] = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reply-to name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReplyToName(): string
|
||||
{
|
||||
return $this->customMailOptions['replyToName'] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function reset(): self
|
||||
{
|
||||
$this->project = null;
|
||||
$this->recipient = '';
|
||||
$this->name = '';
|
||||
$this->subject = '';
|
||||
$this->body = '';
|
||||
$this->variables = [];
|
||||
$this->bodyTemplate = '';
|
||||
$this->attachment = [];
|
||||
$this->customMailOptions = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
$platform = $this->platform;
|
||||
if (empty($platform)) {
|
||||
$platform = Config::getParam('platform', []);
|
||||
}
|
||||
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'recipient' => $this->recipient,
|
||||
'name' => $this->name,
|
||||
'subject' => $this->subject,
|
||||
'bodyTemplate' => $this->bodyTemplate,
|
||||
'body' => $this->body,
|
||||
'preview' => $this->preview,
|
||||
'smtp' => $this->smtp,
|
||||
'variables' => $this->variables,
|
||||
'attachment' => $this->attachment,
|
||||
'customMailOptions' => $this->customMailOptions,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams()),
|
||||
'platform' => $platform,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Message;
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
final class Mail extends Base
|
||||
{
|
||||
public function __construct(
|
||||
public readonly ?Document $project = null,
|
||||
public readonly string $recipient = '',
|
||||
public readonly string $name = '',
|
||||
public readonly string $subject = '',
|
||||
public readonly string $bodyTemplate = '',
|
||||
public readonly string $body = '',
|
||||
public readonly string $preview = '',
|
||||
public readonly array $smtp = [],
|
||||
public readonly array $variables = [],
|
||||
public readonly array $attachment = [],
|
||||
public readonly array $customMailOptions = [],
|
||||
public readonly array $events = [],
|
||||
public readonly array $platform = [],
|
||||
) {
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$platform = !empty($this->platform) ? $this->platform : Config::getParam('platform', []);
|
||||
|
||||
return [
|
||||
'project' => $this->project?->getArrayCopy(),
|
||||
'recipient' => $this->recipient,
|
||||
'name' => $this->name,
|
||||
'subject' => $this->subject,
|
||||
'bodyTemplate' => $this->bodyTemplate,
|
||||
'body' => $this->body,
|
||||
'preview' => $this->preview,
|
||||
'smtp' => $this->smtp,
|
||||
'variables' => $this->variables,
|
||||
'attachment' => $this->attachment,
|
||||
'customMailOptions' => $this->customMailOptions,
|
||||
'events' => $this->events,
|
||||
'platform' => $platform,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
return new self(
|
||||
project: !empty($data['project']) ? new Document($data['project']) : null,
|
||||
recipient: $data['recipient'] ?? '',
|
||||
name: $data['name'] ?? '',
|
||||
subject: $data['subject'] ?? '',
|
||||
bodyTemplate: $data['bodyTemplate'] ?? '',
|
||||
body: $data['body'] ?? '',
|
||||
preview: $data['preview'] ?? '',
|
||||
smtp: $data['smtp'] ?? [],
|
||||
variables: $data['variables'] ?? [],
|
||||
attachment: $data['attachment'] ?? [],
|
||||
customMailOptions: $data['customMailOptions'] ?? [],
|
||||
events: $data['events'] ?? [],
|
||||
platform: $data['platform'] ?? [],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Message;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
|
||||
final class Messaging extends Base
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $type,
|
||||
public readonly Document $project,
|
||||
public readonly ?Document $user = null,
|
||||
public readonly ?string $messageId = null,
|
||||
public readonly ?Document $message = null,
|
||||
public readonly ?array $recipients = null,
|
||||
public readonly ?string $providerType = null,
|
||||
) {
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->type,
|
||||
'project' => $this->project->getArrayCopy(),
|
||||
'user' => $this->user?->getArrayCopy(),
|
||||
'messageId' => $this->messageId,
|
||||
'message' => $this->message?->getArrayCopy(),
|
||||
'recipients' => $this->recipients,
|
||||
'providerType' => $this->providerType,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
return new self(
|
||||
type: $data['type'] ?? '',
|
||||
project: new Document($data['project'] ?? []),
|
||||
user: !empty($data['user']) ? new Document($data['user']) : null,
|
||||
messageId: $data['messageId'] ?? null,
|
||||
message: !empty($data['message']) ? new Document($data['message']) : null,
|
||||
recipients: $data['recipients'] ?? null,
|
||||
providerType: $data['providerType'] ?? null,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\System\System;
|
||||
|
||||
class Messaging extends Event
|
||||
{
|
||||
protected string $type = '';
|
||||
protected ?string $messageId = null;
|
||||
protected ?Document $message = null;
|
||||
protected ?array $recipients = null;
|
||||
protected ?string $scheduledAt = null;
|
||||
protected ?string $providerType = null;
|
||||
|
||||
public function __construct(protected Publisher $publisher)
|
||||
{
|
||||
parent::__construct($publisher);
|
||||
|
||||
$this
|
||||
->setQueue(System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME))
|
||||
->setClass(System::getEnv('_APP_MESSAGING_CLASS_NAME', Event::MESSAGING_CLASS_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets type for the build event.
|
||||
*
|
||||
* @param string $type Can be `MESSAGE_SEND_TYPE_INTERNAL` or `MESSAGE_SEND_TYPE_EXTERNAL`.
|
||||
* @return self
|
||||
*/
|
||||
public function setType(string $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set type for the function event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets recipient for the messaging event.
|
||||
*
|
||||
* @param string[] $recipients
|
||||
* @return self
|
||||
*/
|
||||
public function setRecipients(array $recipients): self
|
||||
{
|
||||
$this->recipients = $recipients;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set recipient for messaging event.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getRecipient(): array
|
||||
{
|
||||
return $this->recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets message document for the messaging event.
|
||||
*
|
||||
* @param Document $message
|
||||
* @return self
|
||||
*/
|
||||
public function setMessage(Document $message): self
|
||||
{
|
||||
$this->message = $message;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns message document for the messaging event.
|
||||
*
|
||||
* @return Document
|
||||
*/
|
||||
public function getMessage(): Document
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets message ID for the messaging event.
|
||||
*
|
||||
* @param string $messageId
|
||||
* @return self
|
||||
*/
|
||||
public function setMessageId(string $messageId): self
|
||||
{
|
||||
$this->messageId = $messageId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set message ID for the messaging event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMessageId(): string
|
||||
{
|
||||
return $this->messageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets provider type for the messaging event.
|
||||
*
|
||||
* @param string $providerType
|
||||
* @return self
|
||||
*/
|
||||
public function setProviderType(string $providerType): self
|
||||
{
|
||||
$this->providerType = $providerType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set provider type for the messaging event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProviderType(): string
|
||||
{
|
||||
return $this->providerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Scheduled delivery time for the messaging event.
|
||||
*
|
||||
* @param string $scheduledAt
|
||||
* @return self
|
||||
*/
|
||||
public function setScheduledAt(string $scheduledAt): self
|
||||
{
|
||||
$this->scheduledAt = $scheduledAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set Delivery Time for the messaging event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheduledAt(): string
|
||||
{
|
||||
return $this->scheduledAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->type,
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'messageId' => $this->messageId,
|
||||
'message' => $this->message,
|
||||
'recipients' => $this->recipients,
|
||||
'providerType' => $this->providerType,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Publisher;
|
||||
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Queue\Queue;
|
||||
|
||||
readonly class Mail extends Base
|
||||
{
|
||||
public function __construct(
|
||||
Publisher $publisher,
|
||||
protected Queue $queue
|
||||
) {
|
||||
parent::__construct($publisher);
|
||||
}
|
||||
|
||||
public function enqueue(MailMessage $message, ?Queue $queue = null): string|bool
|
||||
{
|
||||
return $this->publish($queue ?? $this->queue, $message);
|
||||
}
|
||||
|
||||
public function getSize(bool $failed = false, ?Queue $queue = null): int
|
||||
{
|
||||
return $this->getQueueSize($queue ?? $this->queue, $failed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Publisher;
|
||||
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Queue\Queue;
|
||||
|
||||
readonly class Messaging extends Base
|
||||
{
|
||||
public function __construct(
|
||||
Publisher $publisher,
|
||||
protected Queue $queue
|
||||
) {
|
||||
parent::__construct($publisher);
|
||||
}
|
||||
|
||||
public function enqueue(MessagingMessage $message, ?Queue $queue = null): string|bool
|
||||
{
|
||||
return $this->publish($queue ?? $this->queue, $message);
|
||||
}
|
||||
|
||||
public function getSize(bool $failed = false, ?Queue $queue = null): int
|
||||
{
|
||||
return $this->getQueueSize($queue ?? $this->queue, $failed);
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,7 @@ abstract class Migration
|
||||
'1.9.2' => 'V24',
|
||||
'1.9.3' => 'V24',
|
||||
'1.9.4' => 'V24',
|
||||
'1.9.5' => 'V24',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,10 @@ namespace Appwrite\Platform\Modules\Account\Http\Account\MFA\Challenges;
|
||||
use Appwrite\Auth\MFA\Type;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
@@ -101,8 +103,8 @@ class Create extends Action
|
||||
->inject('platform')
|
||||
->inject('request')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMessaging')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('publisherForMails')
|
||||
->inject('timelimit')
|
||||
->inject('usage')
|
||||
->inject('plan')
|
||||
@@ -121,8 +123,8 @@ class Create extends Action
|
||||
array $platform,
|
||||
Request $request,
|
||||
Event $queueForEvents,
|
||||
Messaging $queueForMessaging,
|
||||
Mail $queueForMails,
|
||||
MessagingPublisher $publisherForMessaging,
|
||||
MailPublisher $publisherForMails,
|
||||
callable $timelimit,
|
||||
Context $usage,
|
||||
array $plan,
|
||||
@@ -180,16 +182,18 @@ class Create extends Action
|
||||
$message = $message->render();
|
||||
|
||||
$phone = $user->getAttribute('phone');
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
||||
->setMessage(new Document([
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_INTERNAL,
|
||||
project: $project,
|
||||
message: new Document([
|
||||
'$id' => $challenge->getId(),
|
||||
'data' => [
|
||||
'content' => $code,
|
||||
],
|
||||
]))
|
||||
->setRecipients([$phone])
|
||||
->setProviderType(MESSAGE_TYPE_SMS);
|
||||
]),
|
||||
recipients: [$phone],
|
||||
providerType: MESSAGE_TYPE_SMS,
|
||||
));
|
||||
|
||||
$helper = PhoneNumberUtil::getInstance();
|
||||
try {
|
||||
@@ -252,6 +256,7 @@ class Create extends Action
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
@@ -269,13 +274,6 @@ class Create extends Action
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -296,11 +294,17 @@ class Create extends Action
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
@@ -327,20 +331,18 @@ class Create extends Action
|
||||
]);
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setBodyTemplate($bodyTemplate)
|
||||
->appendVariables($emailVariables)
|
||||
->setRecipient($user->getAttribute('email'));
|
||||
|
||||
// since this is console project, set email sender name!
|
||||
if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) {
|
||||
$queueForMails->setSenderName($platform['emailSenderName']);
|
||||
}
|
||||
|
||||
$queueForMails->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $user->getAttribute('email'),
|
||||
subject: $subject,
|
||||
bodyTemplate: $bodyTemplate,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: $smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE ? ['senderName' => $platform['emailSenderName']] : [],
|
||||
platform: $platform,
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -287,7 +287,29 @@ class Update extends Base
|
||||
}
|
||||
|
||||
// Inform scheduler if function is still active
|
||||
$schedule = $dbForPlatform->getDocument('schedules', $function->getAttribute('scheduleId'));
|
||||
$schedule = $authorization->skip(fn () => $dbForPlatform->getDocument('schedules', $function->getAttribute('scheduleId')));
|
||||
|
||||
// Re-create schedule if missing
|
||||
if ($schedule->isEmpty()) {
|
||||
$schedule = $authorization->skip(
|
||||
fn () => $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => SCHEDULE_RESOURCE_TYPE_FUNCTION,
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceInternalId' => $function->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $function->getAttribute('schedule'),
|
||||
'active' => false,
|
||||
]))
|
||||
);
|
||||
|
||||
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document([
|
||||
'scheduleId' => $schedule->getId(),
|
||||
'scheduleInternalId' => $schedule->getSequence(),
|
||||
]));
|
||||
}
|
||||
|
||||
$schedule
|
||||
->setAttribute('resourceUpdatedAt', DateTime::now())
|
||||
->setAttribute('schedule', $function->getAttribute('schedule'))
|
||||
|
||||
@@ -6,11 +6,11 @@ use Appwrite\Event\Database;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Publisher\Audit;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Event\Publisher\Certificate;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Event\Publisher\Migration as MigrationPublisher;
|
||||
use Appwrite\Event\Publisher\Screenshot;
|
||||
use Appwrite\Event\Publisher\StatsResources as StatsResourcesPublisher;
|
||||
@@ -77,14 +77,14 @@ class Get extends Base
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForDeletes')
|
||||
->inject('publisherForAudits')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('queueForFunctions')
|
||||
->inject('publisherForStatsResources')
|
||||
->inject('publisherForUsage')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('publisherForCertificates')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('publisherForMigrations')
|
||||
->inject('publisherForScreenshots')
|
||||
->callback($this->action(...));
|
||||
@@ -97,14 +97,14 @@ class Get extends Base
|
||||
Database $queueForDatabase,
|
||||
Delete $queueForDeletes,
|
||||
Audit $publisherForAudits,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Func $queueForFunctions,
|
||||
StatsResourcesPublisher $publisherForStatsResources,
|
||||
UsagePublisher $publisherForUsage,
|
||||
Webhook $queueForWebhooks,
|
||||
Certificate $publisherForCertificates,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
Messaging $queueForMessaging,
|
||||
MessagingPublisher $publisherForMessaging,
|
||||
MigrationPublisher $publisherForMigrations,
|
||||
Screenshot $publisherForScreenshots,
|
||||
): void {
|
||||
@@ -114,7 +114,7 @@ class Get extends Base
|
||||
System::getEnv('_APP_DATABASE_QUEUE_NAME', Event::DATABASE_QUEUE_NAME) => $queueForDatabase,
|
||||
System::getEnv('_APP_DELETE_QUEUE_NAME', Event::DELETE_QUEUE_NAME) => $queueForDeletes,
|
||||
System::getEnv('_APP_AUDITS_QUEUE_NAME', Event::AUDITS_QUEUE_NAME) => $publisherForAudits,
|
||||
System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME) => $queueForMails,
|
||||
System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME) => $publisherForMails,
|
||||
System::getEnv('_APP_FUNCTIONS_QUEUE_NAME', Event::FUNCTIONS_QUEUE_NAME) => $queueForFunctions,
|
||||
System::getEnv('_APP_STATS_RESOURCES_QUEUE_NAME', Event::STATS_RESOURCES_QUEUE_NAME) => $publisherForStatsResources,
|
||||
System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME) => $publisherForUsage,
|
||||
@@ -122,7 +122,7 @@ class Get extends Base
|
||||
System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME) => $publisherForCertificates,
|
||||
System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME) => $publisherForBuilds,
|
||||
System::getEnv('_APP_SCREENSHOTS_QUEUE_NAME', Event::SCREENSHOTS_QUEUE_NAME) => $publisherForScreenshots,
|
||||
System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME) => $queueForMessaging,
|
||||
System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME) => $publisherForMessaging,
|
||||
System::getEnv('_APP_MIGRATIONS_QUEUE_NAME', Event::MIGRATIONS_QUEUE_NAME) => $publisherForMigrations,
|
||||
default => throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unknown queue name: ' . $name),
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Health\Http\Health\Queue\Mails;
|
||||
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Platform\Modules\Health\Http\Health\Queue\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
@@ -42,16 +42,16 @@ class Get extends Base
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(int|string $threshold, Mail $queueForMails, Response $response): void
|
||||
public function action(int|string $threshold, MailPublisher $publisherForMails, Response $response): void
|
||||
{
|
||||
$threshold = (int) $threshold;
|
||||
|
||||
$size = $queueForMails->getSize();
|
||||
$size = $publisherForMails->getSize();
|
||||
|
||||
$this->assertQueueThreshold($size, $threshold);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Health\Http\Health\Queue\Messaging;
|
||||
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Platform\Modules\Health\Http\Health\Queue\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
@@ -42,16 +42,16 @@ class Get extends Base
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(int|string $threshold, Messaging $queueForMessaging, Response $response): void
|
||||
public function action(int|string $threshold, MessagingPublisher $publisherForMessaging, Response $response): void
|
||||
{
|
||||
$threshold = (int) $threshold;
|
||||
|
||||
$size = $queueForMessaging->getSize();
|
||||
$size = $publisherForMessaging->getSize();
|
||||
|
||||
$this->assertQueueThreshold($size, $threshold);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ class Delete extends Action
|
||||
->desc('Delete project')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'project.write')
|
||||
->label('event', 'project.delete')
|
||||
->label('audits.event', 'project.delete')
|
||||
->label('audits.resource', 'project/{project.$id}')
|
||||
->label('sdk', new Method(
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
|
||||
class Get extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'getProject';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/project')
|
||||
->httpAlias('/v1/projects/:projectId')
|
||||
->desc('Get project')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'project.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: null,
|
||||
name: 'get',
|
||||
description: <<<EOT
|
||||
Get a project.
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::NONE
|
||||
))
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
Response $response,
|
||||
Document $project,
|
||||
) {
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\SMTP\Tests;
|
||||
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Extend\Exception as Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -67,7 +68,7 @@ class Create extends Action
|
||||
->param('secure', '', new WhiteList(['tls', 'ssl'], true), 'Does SMTP server use secure connection', optional: true, deprecated: true) // Backwards compatibility
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('plan')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
@@ -87,7 +88,7 @@ class Create extends Action
|
||||
string $paramSecure, // Backwards compatibility
|
||||
Response $response,
|
||||
Document $project,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
array $plan
|
||||
): void {
|
||||
// Backwards compatibility: use inline params if provided, otherwise fall back to project SMTP config.
|
||||
@@ -153,23 +154,24 @@ class Create extends Action
|
||||
->setParam('{{privacyUrl}}', $plan['privacyUrl'] ?? APP_EMAIL_PRIVACY_URL);
|
||||
|
||||
foreach ($emails as $email) {
|
||||
$queueForMails
|
||||
->setSmtpHost($host)
|
||||
->setSmtpPort($port)
|
||||
->setSmtpUsername($username)
|
||||
->setSmtpPassword($password)
|
||||
->setSmtpSecure($secure)
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName)
|
||||
->setRecipient($email)
|
||||
->setName('')
|
||||
->setBodyTemplate(APP_CE_CONFIG_DIR . '/locale/templates/email-base-styled.tpl')
|
||||
->setBody($template->render())
|
||||
->setVariables([])
|
||||
->setSubject($subject)
|
||||
->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $email,
|
||||
subject: $subject,
|
||||
bodyTemplate: APP_CE_CONFIG_DIR . '/locale/templates/email-base-styled.tpl',
|
||||
body: $template->render(),
|
||||
smtp: [
|
||||
'host' => $host,
|
||||
'port' => $port,
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'secure' => $secure,
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
$response->noContent();
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Project\Services;
|
||||
use Appwrite\Platform\Modules\Project\Http\Init;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\AuthMethods\Update as UpdateAuthMethod;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\Delete as DeleteProject;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\Get as GetProject;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Create as CreateKey;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Delete as DeleteKey;
|
||||
use Appwrite\Platform\Modules\Project\Http\Project\Keys\Ephemeral\Create as CreateEphemeralKey;
|
||||
@@ -110,6 +111,7 @@ class Http extends Service
|
||||
|
||||
// Project
|
||||
$this->addAction(DeleteProject::getName(), new DeleteProject());
|
||||
$this->addAction(GetProject::getName(), new GetProject());
|
||||
$this->addAction(UpdateProjectLabels::getName(), new UpdateProjectLabels());
|
||||
$this->addAction(UpdateProjectProtocol::getName(), new UpdateProjectProtocol());
|
||||
$this->addAction(UpdateProjectService::getName(), new UpdateProjectService());
|
||||
|
||||
@@ -28,7 +28,6 @@ use Utopia\Pools\Group;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Create extends Action
|
||||
@@ -72,15 +71,6 @@ class Create extends Action
|
||||
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('region', System::getEnv('_APP_REGION', 'default'), new WhiteList(array_keys(array_filter(Config::getParam('regions'), fn ($config) => !$config['disabled']))), 'Project Region.', true)
|
||||
->param('description', '', new Text(256), 'Project description. Max length: 256 chars.', true)
|
||||
->param('logo', '', new Text(1024), 'Project logo.', true)
|
||||
->param('url', '', new URL(), 'Project URL.', true)
|
||||
->param('legalName', '', new Text(256), 'Project legal Name. Max length: 256 chars.', true)
|
||||
->param('legalCountry', '', new Text(256), 'Project legal Country. Max length: 256 chars.', true)
|
||||
->param('legalState', '', new Text(256), 'Project legal State. Max length: 256 chars.', true)
|
||||
->param('legalCity', '', new Text(256), 'Project legal City. Max length: 256 chars.', true)
|
||||
->param('legalAddress', '', new Text(256), 'Project legal Address. Max length: 256 chars.', true)
|
||||
->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -90,7 +80,7 @@ class Create extends Action
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Request $request, Response $response, Database $dbForPlatform, Cache $cache, Group $pools, Hooks $hooks)
|
||||
public function action(string $projectId, string $name, string $teamId, string $region, Request $request, Response $response, Database $dbForPlatform, Cache $cache, Group $pools, Hooks $hooks)
|
||||
{
|
||||
$team = $dbForPlatform->getDocument('teams', $teamId);
|
||||
|
||||
@@ -175,16 +165,7 @@ class Create extends Action
|
||||
'teamInternalId' => $team->getSequence(),
|
||||
'teamId' => $team->getId(),
|
||||
'region' => $region,
|
||||
'description' => $description,
|
||||
'logo' => $logo,
|
||||
'url' => $url,
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'legalName' => $legalName,
|
||||
'legalCountry' => $legalCountry,
|
||||
'legalState' => $legalState,
|
||||
'legalCity' => $legalCity,
|
||||
'legalAddress' => $legalAddress,
|
||||
'legalTaxId' => ID::custom($legalTaxId),
|
||||
'services' => new \stdClass(),
|
||||
'platforms' => null,
|
||||
'oAuthProviders' => [],
|
||||
|
||||
@@ -4,8 +4,10 @@ namespace Appwrite\Platform\Modules\Teams\Http\Memberships;
|
||||
|
||||
use Appwrite\Auth\Validator\Phone;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -87,18 +89,19 @@ class Create extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMails')
|
||||
->inject('publisherForMessaging')
|
||||
->inject('queueForEvents')
|
||||
->inject('timelimit')
|
||||
->inject('usage')
|
||||
->inject('plan')
|
||||
->inject('platform')
|
||||
->inject('proofForPassword')
|
||||
->inject('proofForToken')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, User $user, Database $dbForProject, Authorization $authorization, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, callable $timelimit, Context $usage, array $plan, Password $proofForPassword, Token $proofForToken)
|
||||
public function action(string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, User $user, Database $dbForProject, Authorization $authorization, Locale $locale, MailPublisher $publisherForMails, MessagingPublisher $publisherForMessaging, Event $queueForEvents, callable $timelimit, Context $usage, array $plan, array $platform, Password $proofForPassword, Token $proofForToken)
|
||||
{
|
||||
$isAppUser = $user->isApp($authorization->getRoles());
|
||||
$isPrivilegedUser = $user->isPrivileged($authorization->getRoles());
|
||||
@@ -345,6 +348,7 @@ class Create extends Action
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyToEmail = '';
|
||||
$replyToName = '';
|
||||
$smtpConfig = [];
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (! empty($smtp['senderEmail'])) {
|
||||
@@ -362,13 +366,6 @@ class Create extends Action
|
||||
$replyToName = $smtp['replyToName'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (! empty($customTemplate)) {
|
||||
if (! empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
@@ -389,11 +386,17 @@ class Create extends Action
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyToEmail($replyToEmail)
|
||||
->setSmtpReplyToName($replyToName)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
$smtpConfig = [
|
||||
'host' => $smtp['host'] ?? '',
|
||||
'port' => $smtp['port'] ?? '',
|
||||
'username' => $smtp['username'] ?? '',
|
||||
'password' => $smtp['password'] ?? '',
|
||||
'secure' => $smtp['secure'] ?? '',
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'senderEmail' => $senderEmail,
|
||||
'senderName' => $senderName,
|
||||
];
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
@@ -406,14 +409,17 @@ class Create extends Action
|
||||
'project' => $projectName,
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setBody($body)
|
||||
->setPreview($preview)
|
||||
->setRecipient($invitee->getAttribute('email'))
|
||||
->setName($invitee->getAttribute('name', ''))
|
||||
->appendVariables($emailVariables)
|
||||
->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $invitee->getAttribute('email'),
|
||||
name: $invitee->getAttribute('name', ''),
|
||||
subject: $subject,
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
smtp: $smtpConfig,
|
||||
variables: $emailVariables,
|
||||
platform: $platform,
|
||||
));
|
||||
} elseif (! empty($phone)) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
@@ -431,11 +437,13 @@ class Create extends Action
|
||||
],
|
||||
]);
|
||||
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_INTERNAL)
|
||||
->setMessage($messageDoc)
|
||||
->setRecipients([$phone])
|
||||
->setProviderType('SMS');
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_INTERNAL,
|
||||
project: $project,
|
||||
message: $messageDoc,
|
||||
recipients: [$phone],
|
||||
providerType: 'SMS',
|
||||
));
|
||||
|
||||
$helper = PhoneNumberUtil::getInstance();
|
||||
try {
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
|
||||
namespace Appwrite\Platform\Tasks;
|
||||
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Message\Messaging as MessagingMessage;
|
||||
use Appwrite\Event\Publisher\Messaging as MessagingPublisher;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Queue\Queue;
|
||||
use Utopia\System\System;
|
||||
|
||||
class ScheduleMessages extends ScheduleBase
|
||||
{
|
||||
public const UPDATE_TIMER = 3; // seconds
|
||||
public const ENQUEUE_TIMER = 4; // seconds
|
||||
|
||||
private ?MessagingPublisher $publisherForMessaging = null;
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'schedule-messages';
|
||||
@@ -27,6 +33,11 @@ class ScheduleMessages extends ScheduleBase
|
||||
|
||||
protected function enqueueResources(Database $dbForPlatform, callable $getProjectDB): void
|
||||
{
|
||||
$publisherForMessaging = $this->publisherForMessaging ??= new MessagingPublisher(
|
||||
$this->publisherMessaging,
|
||||
new Queue(System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME))
|
||||
);
|
||||
|
||||
foreach ($this->schedules as $schedule) {
|
||||
if (!$schedule['active']) {
|
||||
continue;
|
||||
@@ -39,16 +50,14 @@ class ScheduleMessages extends ScheduleBase
|
||||
continue;
|
||||
}
|
||||
|
||||
\go(function () use ($schedule, $scheduledAt, $dbForPlatform) {
|
||||
$queueForMessaging = new Messaging($this->publisherMessaging);
|
||||
|
||||
\go(function () use ($schedule, $scheduledAt, $dbForPlatform, $publisherForMessaging) {
|
||||
$this->updateProjectAccess($schedule['project'], $dbForPlatform);
|
||||
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($schedule['resourceId'])
|
||||
->setProject($schedule['project'])
|
||||
->trigger();
|
||||
$publisherForMessaging->enqueue(new MessagingMessage(
|
||||
type: MESSAGE_SEND_TYPE_EXTERNAL,
|
||||
project: $schedule['project'],
|
||||
messageId: $schedule['resourceId'],
|
||||
));
|
||||
|
||||
$dbForPlatform->deleteDocument(
|
||||
'schedules',
|
||||
|
||||
@@ -5,8 +5,9 @@ namespace Appwrite\Platform\Workers;
|
||||
use Appwrite\Certificates\Adapter as CertificatesAdapter;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Publisher\Certificate;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
@@ -50,7 +51,7 @@ class Certificates extends Action
|
||||
->desc('Certificates worker')
|
||||
->inject('message')
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForFunctions')
|
||||
@@ -66,7 +67,7 @@ class Certificates extends Action
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param Event $queueForEvents
|
||||
* @param Webhook $queueForWebhooks
|
||||
* @param Func $queueForFunctions
|
||||
@@ -83,7 +84,7 @@ class Certificates extends Action
|
||||
public function action(
|
||||
Message $message,
|
||||
Database $dbForPlatform,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Event $queueForEvents,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
@@ -116,7 +117,7 @@ class Certificates extends Action
|
||||
break;
|
||||
|
||||
case \Appwrite\Event\Certificate::ACTION_GENERATION:
|
||||
$this->handleCertificateGenerationAction($domain, $domainType, $dbForPlatform, $queueForMails, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $log, $certificates, $authorization, $skipRenewCheck, $plan, $validationDomain);
|
||||
$this->handleCertificateGenerationAction($domain, $domainType, $dbForPlatform, $publisherForMails, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $log, $certificates, $authorization, $skipRenewCheck, $plan, $validationDomain);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -209,7 +210,7 @@ class Certificates extends Action
|
||||
* @param Domain $domain
|
||||
* @param ?string $domainType
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param Event $queueForEvents
|
||||
* @param Webhook $queueForWebhooks
|
||||
* @param Func $queueForFunctions
|
||||
@@ -233,7 +234,7 @@ class Certificates extends Action
|
||||
Domain $domain,
|
||||
?string $domainType,
|
||||
Database $dbForPlatform,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Event $queueForEvents,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
@@ -358,7 +359,7 @@ class Certificates extends Action
|
||||
$rule->setAttribute('status', RULE_STATUS_CERTIFICATE_GENERATION_FAILED);
|
||||
|
||||
// Send email to security email
|
||||
$this->notifyError($domain->get(), $e->getMessage(), $attempts, $queueForMails, $plan);
|
||||
$this->notifyError($domain->get(), $e->getMessage(), $attempts, $publisherForMails, $plan);
|
||||
|
||||
throw $e;
|
||||
} finally {
|
||||
@@ -524,12 +525,12 @@ class Certificates extends Action
|
||||
* @param string $domain Domain that caused the error
|
||||
* @param string $errorMessage Verbose error message
|
||||
* @param int $attempt How many times it failed already
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param array $plan
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function notifyError(string $domain, string $errorMessage, int $attempt, Mail $queueForMails, array $plan): void
|
||||
private function notifyError(string $domain, string $errorMessage, int $attempt, MailPublisher $publisherForMails, array $plan): void
|
||||
{
|
||||
// Log error into console
|
||||
Console::warning('Cannot renew domain (' . $domain . ') on attempt no. ' . $attempt . ' certificate: ' . $errorMessage);
|
||||
@@ -560,14 +561,14 @@ class Certificates extends Action
|
||||
$subject = $locale->getText("emails.certificate.subject");
|
||||
$preview = $locale->getText("emails.certificate.preview");
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setName('Appwrite Administrator')
|
||||
->setBodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl')
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient(System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')))
|
||||
->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
recipient: System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')),
|
||||
name: 'Appwrite Administrator',
|
||||
subject: $subject,
|
||||
bodyTemplate: __DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl',
|
||||
body: $body,
|
||||
preview: $preview,
|
||||
variables: $emailVariables,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
namespace Appwrite\Platform\Workers;
|
||||
|
||||
use Ahc\Jwt\JWT;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Message\Migration;
|
||||
use Appwrite\Event\Message\Usage as UsageMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Usage as UsagePublisher;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Extend\Exception;
|
||||
@@ -102,7 +103,7 @@ class Migrations extends Action
|
||||
->inject('queueForRealtime')
|
||||
->inject('deviceForMigrations')
|
||||
->inject('deviceForFiles')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('usage')
|
||||
->inject('publisherForUsage')
|
||||
->inject('plan')
|
||||
@@ -124,7 +125,7 @@ class Migrations extends Action
|
||||
Realtime $queueForRealtime,
|
||||
Device $deviceForMigrations,
|
||||
Device $deviceForFiles,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Context $usage,
|
||||
UsagePublisher $publisherForUsage,
|
||||
array $plan,
|
||||
@@ -163,7 +164,7 @@ class Migrations extends Action
|
||||
$this->processMigration(
|
||||
$migration,
|
||||
$queueForRealtime,
|
||||
$queueForMails,
|
||||
$publisherForMails,
|
||||
$usage,
|
||||
$publisherForUsage,
|
||||
$platform,
|
||||
@@ -440,7 +441,7 @@ class Migrations extends Action
|
||||
protected function processMigration(
|
||||
Document $migration,
|
||||
Realtime $queueForRealtime,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Context $usage,
|
||||
UsagePublisher $publisherForUsage,
|
||||
array $platform,
|
||||
@@ -644,7 +645,7 @@ class Migrations extends Action
|
||||
}
|
||||
$destination_type = $migration->getAttribute('destination');
|
||||
if ($destination_type === DestinationCSV::getName() || $destination_type === DestinationJSON::getName()) {
|
||||
$this->handleDataExportComplete($project, $migration, $queueForMails, $queueForRealtime, $platform, $authorization);
|
||||
$this->handleDataExportComplete($project, $migration, $publisherForMails, $queueForRealtime, $platform, $authorization);
|
||||
}
|
||||
} finally {
|
||||
$source?->cleanup();
|
||||
@@ -671,7 +672,7 @@ class Migrations extends Action
|
||||
*
|
||||
* @param Document $project
|
||||
* @param Document $migration
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param Realtime $queueForRealtime
|
||||
* @param array $platform
|
||||
* @param Authorization $authorization
|
||||
@@ -680,7 +681,7 @@ class Migrations extends Action
|
||||
protected function handleDataExportComplete(
|
||||
Document $project,
|
||||
Document $migration,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
Realtime $queueForRealtime,
|
||||
array $platform,
|
||||
Authorization $authorization,
|
||||
@@ -732,7 +733,7 @@ class Migrations extends Action
|
||||
project: $project,
|
||||
user: $user,
|
||||
options: $options,
|
||||
queueForMails: $queueForMails,
|
||||
publisherForMails: $publisherForMails,
|
||||
platform: $platform,
|
||||
exportType: $migration->getAttribute('destination') === DestinationJSON::getName() ? 'JSON' : 'CSV',
|
||||
sizeMB: $sizeMB
|
||||
@@ -795,7 +796,7 @@ class Migrations extends Action
|
||||
project: $project,
|
||||
user: $user,
|
||||
options: $options,
|
||||
queueForMails: $queueForMails,
|
||||
publisherForMails: $publisherForMails,
|
||||
platform: $platform,
|
||||
exportType: $migration->getAttribute('destination') === DestinationJSON::getName() ? 'JSON' : 'CSV',
|
||||
downloadUrl: $downloadUrl
|
||||
@@ -809,7 +810,7 @@ class Migrations extends Action
|
||||
* @param Document $project
|
||||
* @param Document $user The user who triggered the operation
|
||||
* @param array $options Migration options
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param array $platform
|
||||
* @param string $downloadUrl Download URL for successful exports
|
||||
* @param float $sizeMB File size in MB for failed exports
|
||||
@@ -821,7 +822,7 @@ class Migrations extends Action
|
||||
Document $project,
|
||||
Document $user,
|
||||
array $options,
|
||||
Mail $queueForMails,
|
||||
MailPublisher $publisherForMails,
|
||||
array $platform,
|
||||
string $exportType = 'CSV',
|
||||
string $downloadUrl = '',
|
||||
@@ -891,17 +892,18 @@ class Migrations extends Action
|
||||
'type' => $exportType,
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setProject($project)
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($emailBody)
|
||||
->setBodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl')
|
||||
->setVariables($emailVariables)
|
||||
->setName($user->getAttribute('name', $user->getAttribute('email')))
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setSenderName($platform['emailSenderName'])
|
||||
->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $user->getAttribute('email'),
|
||||
name: $user->getAttribute('name', $user->getAttribute('email')),
|
||||
subject: $subject,
|
||||
bodyTemplate: __DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl',
|
||||
body: $emailBody,
|
||||
preview: $preview,
|
||||
variables: $emailVariables,
|
||||
customMailOptions: ['senderName' => $platform['emailSenderName']],
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
Console::info("CSV export {$emailType} notification email sent to " . $user->getAttribute('email'));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Appwrite\Platform\Workers;
|
||||
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Message\Mail as MailMessage;
|
||||
use Appwrite\Event\Message\Usage as UsageMessage;
|
||||
use Appwrite\Event\Publisher\Mail as MailPublisher;
|
||||
use Appwrite\Event\Publisher\Usage as UsagePublisher;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Usage\Context as UsageContext;
|
||||
@@ -36,7 +37,7 @@ class Webhooks extends Action
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForMails')
|
||||
->inject('publisherForMails')
|
||||
->inject('publisherForUsage')
|
||||
->inject('log')
|
||||
->inject('plan')
|
||||
@@ -47,14 +48,14 @@ class Webhooks extends Action
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param UsagePublisher $publisherForUsage
|
||||
* @param Log $log
|
||||
* @param array $plan
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, Mail $queueForMails, UsagePublisher $publisherForUsage, Log $log, array $plan): void
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, MailPublisher $publisherForMails, UsagePublisher $publisherForUsage, Log $log, array $plan): void
|
||||
{
|
||||
$this->errors = [];
|
||||
$payload = $message->getPayload();
|
||||
@@ -73,7 +74,7 @@ class Webhooks extends Action
|
||||
|
||||
foreach ($project->getAttribute('webhooks', []) as $webhook) {
|
||||
if (array_intersect($webhook->getAttribute('events', []), $events)) {
|
||||
$this->execute($events, $webhookPayload, $webhook, $user, $project, $dbForPlatform, $queueForMails, $publisherForUsage, $plan);
|
||||
$this->execute($events, $webhookPayload, $webhook, $user, $project, $dbForPlatform, $publisherForMails, $publisherForUsage, $plan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,11 +90,11 @@ class Webhooks extends Action
|
||||
* @param Document $user
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param array $plan
|
||||
* @return void
|
||||
*/
|
||||
private function execute(array $events, string $payload, Document $webhook, Document $user, Document $project, Database $dbForPlatform, Mail $queueForMails, UsagePublisher $publisherForUsage, array $plan): void
|
||||
private function execute(array $events, string $payload, Document $webhook, Document $user, Document $project, Database $dbForPlatform, MailPublisher $publisherForMails, UsagePublisher $publisherForUsage, array $plan): void
|
||||
{
|
||||
if ($webhook->getAttribute('enabled') !== true) {
|
||||
return;
|
||||
@@ -171,7 +172,7 @@ class Webhooks extends Action
|
||||
if ($attempts >= \intval(System::getEnv('_APP_WEBHOOK_MAX_FAILED_ATTEMPTS', '10'))) {
|
||||
$webhook->setAttribute('enabled', false);
|
||||
$updatePayload['enabled'] = false;
|
||||
$this->sendEmailAlert($attempts, $statusCode, $webhook, $project, $dbForPlatform, $queueForMails, $plan);
|
||||
$this->sendEmailAlert($attempts, $statusCode, $webhook, $project, $dbForPlatform, $publisherForMails, $plan);
|
||||
}
|
||||
|
||||
$dbForPlatform->updateDocument('webhooks', $webhook->getId(), new Document($updatePayload));
|
||||
@@ -203,11 +204,11 @@ class Webhooks extends Action
|
||||
* @param Document $webhook
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param MailPublisher $publisherForMails
|
||||
* @param array $plan
|
||||
* @return void
|
||||
*/
|
||||
public function sendEmailAlert(int $attempts, mixed $statusCode, Document $webhook, Document $project, Database $dbForPlatform, Mail $queueForMails, array $plan): void
|
||||
public function sendEmailAlert(int $attempts, mixed $statusCode, Document $webhook, Document $project, Database $dbForPlatform, MailPublisher $publisherForMails, array $plan): void
|
||||
{
|
||||
$memberships = $dbForPlatform->find('memberships', [
|
||||
Query::equal('teamInternalId', [$project->getAttribute('teamInternalId')]),
|
||||
@@ -251,18 +252,16 @@ class Webhooks extends Action
|
||||
->setParam('{{message}}', $template->render())
|
||||
->setParam('{{year}}', date("Y"));
|
||||
|
||||
$queueForMails
|
||||
->setProject($project)
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body->render());
|
||||
|
||||
foreach ($users as $user) {
|
||||
$queueForMails
|
||||
->setVariables(['user' => $user->getAttribute('name', '')])
|
||||
->setName($user->getAttribute('name', ''))
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->trigger();
|
||||
$publisherForMails->enqueue(new MailMessage(
|
||||
project: $project,
|
||||
recipient: $user->getAttribute('email'),
|
||||
name: $user->getAttribute('name', ''),
|
||||
subject: $subject,
|
||||
body: $body->render(),
|
||||
preview: $preview,
|
||||
variables: ['user' => $user->getAttribute('name', '')],
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Request\Filters;
|
||||
|
||||
use Appwrite\Utopia\Request\Filter;
|
||||
|
||||
class V26 extends Filter
|
||||
{
|
||||
// Convert 1.9.4 params to 1.9.5
|
||||
public function parse(array $content, string $model): array
|
||||
{
|
||||
switch ($model) {
|
||||
case 'projects.create':
|
||||
$content = $this->stripProjectMetadata($content);
|
||||
break;
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
protected function stripProjectMetadata(array $content): array
|
||||
{
|
||||
unset(
|
||||
$content['description'],
|
||||
$content['logo'],
|
||||
$content['url'],
|
||||
$content['legalName'],
|
||||
$content['legalCountry'],
|
||||
$content['legalState'],
|
||||
$content['legalCity'],
|
||||
$content['legalAddress'],
|
||||
$content['legalTaxId'],
|
||||
);
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -249,6 +249,9 @@ class Response extends SwooleResponse
|
||||
// Project
|
||||
public const MODEL_PROJECT = 'project';
|
||||
public const MODEL_PROJECT_LIST = 'projectList';
|
||||
public const MODEL_PROJECT_AUTH_METHOD = 'projectAuthMethod';
|
||||
public const MODEL_PROJECT_SERVICE = 'projectService';
|
||||
public const MODEL_PROJECT_PROTOCOL = 'projectProtocol';
|
||||
public const MODEL_WEBHOOK = 'webhook';
|
||||
public const MODEL_WEBHOOK_LIST = 'webhookList';
|
||||
public const MODEL_KEY = 'key';
|
||||
@@ -442,9 +445,10 @@ class Response extends SwooleResponse
|
||||
return isset(self::$models[$key]);
|
||||
}
|
||||
|
||||
public function applyFilters(array $data, string $model): array
|
||||
public function applyFilters(array $data, string $model, Document $raw): array
|
||||
{
|
||||
foreach ($this->filters as $filter) {
|
||||
$filter->setRawContent($raw);
|
||||
$data = $filter->parse($data, $model);
|
||||
}
|
||||
|
||||
@@ -464,7 +468,7 @@ class Response extends SwooleResponse
|
||||
public function dynamic(Document $document, string $model): void
|
||||
{
|
||||
$output = $this->output(clone $document, $model);
|
||||
$output = $this->applyFilters($output, $model);
|
||||
$output = $this->applyFilters($output, $model, raw: clone $document);
|
||||
|
||||
switch ($this->getContentType()) {
|
||||
case self::CONTENT_TYPE_JSON:
|
||||
|
||||
@@ -2,8 +2,15 @@
|
||||
|
||||
namespace Appwrite\Utopia\Response;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
|
||||
abstract class Filter
|
||||
{
|
||||
/**
|
||||
* @var ?Document $rawContent
|
||||
*/
|
||||
protected ?Document $rawContent = null;
|
||||
|
||||
/**
|
||||
* Parse the content to another format.
|
||||
*
|
||||
@@ -14,6 +21,10 @@ abstract class Filter
|
||||
*/
|
||||
abstract public function parse(array $content, string $model): array;
|
||||
|
||||
public function setRawContent(Document $rawContent): void
|
||||
{
|
||||
$this->rawContent = $rawContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle list
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Filters;
|
||||
|
||||
use Appwrite\Network\Platform;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Filter;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
// Convert 1.9.5 Data format to 1.9.4 format
|
||||
class V26 extends Filter
|
||||
{
|
||||
public function parse(array $content, string $model): array
|
||||
{
|
||||
return match ($model) {
|
||||
Response::MODEL_PROJECT => $this->parseProject($content, $this->rawContent),
|
||||
Response::MODEL_PROJECT_LIST => $this->handleList($content, 'projects', function ($item) {
|
||||
$projectId = $item['$id'] ?? '';
|
||||
|
||||
$rawProjects = $this->rawContent->getAttribute('projects', []);
|
||||
$rawProject = new Document();
|
||||
foreach ($rawProjects as $rawItem) {
|
||||
if ($rawItem->getId() === $projectId) {
|
||||
$rawProject = $rawItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->parseProject($item, $rawProject);
|
||||
}),
|
||||
default => $content,
|
||||
};
|
||||
}
|
||||
|
||||
private function parseProject(array $content, Document $raw): array
|
||||
{
|
||||
$this->expandAuthMethods($content);
|
||||
$this->expandServices($content);
|
||||
$this->expandProtocols($content);
|
||||
|
||||
unset($content['authMethods'], $content['services'], $content['protocols']);
|
||||
|
||||
$auths = new Document($raw->getAttribute('auths', []));
|
||||
$content['authLimit'] = $auths->getAttribute('limit', 0);
|
||||
$content['authDuration'] = $auths->getAttribute('duration', TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$content['authSessionsLimit'] = $auths->getAttribute('maxSessions', 0);
|
||||
$content['authPasswordHistory'] = $auths->getAttribute('passwordHistory', 0);
|
||||
$content['authPasswordDictionary'] = $auths->getAttribute('passwordDictionary', false);
|
||||
$content['authPersonalDataCheck'] = $auths->getAttribute('personalDataCheck', false);
|
||||
$content['authDisposableEmails'] = $auths->getAttribute('disposableEmails', false);
|
||||
$content['authCanonicalEmails'] = $auths->getAttribute('canonicalEmails', false);
|
||||
$content['authFreeEmails'] = $auths->getAttribute('freeEmails', false);
|
||||
$content['authMockNumbers'] = $auths->getAttribute('mockNumbers', []);
|
||||
$content['authSessionAlerts'] = $auths->getAttribute('sessionAlerts', false);
|
||||
$content['authMembershipsUserName'] = $auths->getAttribute('membershipsUserName', false);
|
||||
$content['authMembershipsUserEmail'] = $auths->getAttribute('membershipsUserEmail', false);
|
||||
$content['authMembershipsMfa'] = $auths->getAttribute('membershipsMfa', false);
|
||||
$content['authMembershipsUserId'] = $auths->getAttribute('membershipsUserId', false);
|
||||
$content['authMembershipsUserPhone'] = $auths->getAttribute('membershipsUserPhone', false);
|
||||
$content['authInvalidateSessions'] = $auths->getAttribute('invalidateSessions', false);
|
||||
|
||||
$content['description'] = $raw->getAttribute('description', '');
|
||||
$content['logo'] = $raw->getAttribute('logo', '');
|
||||
$content['url'] = $raw->getAttribute('url', '');
|
||||
$content['legalName'] = $raw->getAttribute('legalName', '');
|
||||
$content['legalCountry'] = $raw->getAttribute('legalCountry', '');
|
||||
$content['legalState'] = $raw->getAttribute('legalState', '');
|
||||
$content['legalCity'] = $raw->getAttribute('legalCity', '');
|
||||
$content['legalAddress'] = $raw->getAttribute('legalAddress', '');
|
||||
$content['legalTaxId'] = $raw->getAttribute('legalTaxId', '');
|
||||
|
||||
$content['oAuthProviders'] = $this->expandOAuthProviders($raw);
|
||||
|
||||
$content['platforms'] = [];
|
||||
foreach ($raw->getAttribute('platforms', []) as $platform) {
|
||||
$content['platforms'][] = $this->parsePlatform($platform);
|
||||
}
|
||||
|
||||
$content['webhooks'] = [];
|
||||
foreach ($raw->getAttribute('webhooks', []) as $webhook) {
|
||||
$content['webhooks'][] = $this->parseWebhook($webhook);
|
||||
}
|
||||
|
||||
$content['keys'] = [];
|
||||
foreach ($raw->getAttribute('keys', []) as $key) {
|
||||
$content['keys'][] = $this->parseKey($key);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function parsePlatform(Document $platform): array
|
||||
{
|
||||
$type = $platform->getAttribute('type', '');
|
||||
$key = $platform->getAttribute('key', '');
|
||||
|
||||
$result = [
|
||||
'$id' => $platform->getAttribute('$id', ''),
|
||||
'$createdAt' => $platform->getAttribute('$createdAt', ''),
|
||||
'$updatedAt' => $platform->getAttribute('$updatedAt', ''),
|
||||
'name' => $platform->getAttribute('name', ''),
|
||||
'type' => $type,
|
||||
];
|
||||
|
||||
switch ($type) {
|
||||
case Platform::TYPE_ANDROID:
|
||||
$result['applicationId'] = $key;
|
||||
break;
|
||||
case Platform::TYPE_APPLE:
|
||||
$result['bundleIdentifier'] = $key;
|
||||
break;
|
||||
case Platform::TYPE_LINUX:
|
||||
$result['packageName'] = $key;
|
||||
break;
|
||||
case Platform::TYPE_WINDOWS:
|
||||
$result['packageIdentifierName'] = $key;
|
||||
break;
|
||||
default:
|
||||
// Web and backwards-compatibility types are mapped to web
|
||||
$result['hostname'] = $platform->getAttribute('hostname', '');
|
||||
$result['key'] = $key;
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function parseWebhook(Document $webhook): array
|
||||
{
|
||||
return [
|
||||
'$id' => $webhook->getAttribute('$id', ''),
|
||||
'$createdAt' => $webhook->getAttribute('$createdAt', ''),
|
||||
'$updatedAt' => $webhook->getAttribute('$updatedAt', ''),
|
||||
'name' => $webhook->getAttribute('name', ''),
|
||||
'url' => $webhook->getAttribute('url', ''),
|
||||
'events' => $webhook->getAttribute('events', []),
|
||||
'tls' => $webhook->getAttribute('security', true),
|
||||
'authUsername' => $webhook->getAttribute('httpUser', ''),
|
||||
'authPassword' => $webhook->getAttribute('httpPass', ''),
|
||||
'secret' => $webhook->getAttribute('signatureKey', ''),
|
||||
'enabled' => $webhook->getAttribute('enabled', true),
|
||||
'logs' => $webhook->getAttribute('logs', ''),
|
||||
'attempts' => $webhook->getAttribute('attempts', 0),
|
||||
];
|
||||
}
|
||||
|
||||
private function parseKey(Document $key): array
|
||||
{
|
||||
return [
|
||||
'$id' => $key->getAttribute('$id', ''),
|
||||
'$createdAt' => $key->getAttribute('$createdAt', ''),
|
||||
'$updatedAt' => $key->getAttribute('$updatedAt', ''),
|
||||
'name' => $key->getAttribute('name', ''),
|
||||
'expire' => $key->getAttribute('expire', ''),
|
||||
'scopes' => $key->getAttribute('scopes', []),
|
||||
'secret' => $key->getAttribute('secret', ''),
|
||||
'accessedAt' => $key->getAttribute('accessedAt', ''),
|
||||
'sdks' => $key->getAttribute('sdks', []),
|
||||
];
|
||||
}
|
||||
|
||||
private function expandAuthMethods(array &$content): void
|
||||
{
|
||||
$authMethods = [];
|
||||
foreach ($content['authMethods'] ?? [] as $method) {
|
||||
$authMethods[$method['$id'] ?? ''] = $method['enabled'] ?? true;
|
||||
}
|
||||
|
||||
foreach (Config::getParam('auth', []) as $id => $method) {
|
||||
$key = $method['key'] ?? '';
|
||||
$content['auth' . ucfirst($key)] = $authMethods[$id] ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
private function expandServices(array &$content): void
|
||||
{
|
||||
$services = [];
|
||||
foreach ($content['services'] ?? [] as $service) {
|
||||
$services[$service['$id'] ?? ''] = $service['enabled'] ?? true;
|
||||
}
|
||||
|
||||
foreach (Config::getParam('services', []) as $id => $service) {
|
||||
if (!($service['optional'] ?? false)) {
|
||||
continue;
|
||||
}
|
||||
$key = $service['key'] ?? '';
|
||||
$content['serviceStatusFor' . ucfirst($key)] = $services[$id] ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
private function expandProtocols(array &$content): void
|
||||
{
|
||||
$protocols = [];
|
||||
foreach ($content['protocols'] ?? [] as $protocol) {
|
||||
$protocols[$protocol['$id'] ?? ''] = $protocol['enabled'] ?? true;
|
||||
}
|
||||
|
||||
foreach (Config::getParam('protocols', []) as $id => $api) {
|
||||
$key = $api['key'] ?? '';
|
||||
$content['protocolStatusFor' . ucfirst($key)] = $protocols[$id] ?? true;
|
||||
}
|
||||
}
|
||||
|
||||
private function expandOAuthProviders(Document $raw): array
|
||||
{
|
||||
$providers = Config::getParam('oAuthProviders', []);
|
||||
$providerValues = $raw->getAttribute('oAuthProviders', []);
|
||||
$projectProviders = [];
|
||||
|
||||
foreach ($providers as $key => $provider) {
|
||||
if (!($provider['enabled'] ?? false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$projectProviders[] = [
|
||||
'key' => $key,
|
||||
'name' => $provider['name'] ?? '',
|
||||
'appId' => $providerValues[$key . 'Appid'] ?? '',
|
||||
'secret' => '',
|
||||
'enabled' => $providerValues[$key . 'Enabled'] ?? false,
|
||||
];
|
||||
}
|
||||
|
||||
return $projectProviders;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ class Project extends Model
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
// Basic project information
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project ID.',
|
||||
@@ -36,210 +37,23 @@ class Project extends Model
|
||||
'default' => '',
|
||||
'example' => 'New Project',
|
||||
])
|
||||
->addRule('description', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project description.',
|
||||
'default' => '',
|
||||
'example' => 'This is a new project.',
|
||||
])
|
||||
->addRule('teamId', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project team ID.',
|
||||
'default' => '',
|
||||
'example' => '1592981250',
|
||||
])
|
||||
->addRule('logo', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project logo file ID.',
|
||||
'default' => '',
|
||||
'example' => '5f5c451b403cb',
|
||||
])
|
||||
->addRule('url', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project website URL.',
|
||||
'default' => '',
|
||||
'example' => '5f5c451b403cb',
|
||||
])
|
||||
->addRule('legalName', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Company legal name.',
|
||||
'default' => '',
|
||||
'example' => 'Company LTD.',
|
||||
])
|
||||
->addRule('legalCountry', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Country code in [ISO 3166-1](http://en.wikipedia.org/wiki/ISO_3166-1) two-character format.',
|
||||
'default' => '',
|
||||
'example' => 'US',
|
||||
])
|
||||
->addRule('legalState', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'State name.',
|
||||
'default' => '',
|
||||
'example' => 'New York',
|
||||
])
|
||||
->addRule('legalCity', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'City name.',
|
||||
'default' => '',
|
||||
'example' => 'New York City.',
|
||||
])
|
||||
->addRule('legalAddress', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Company Address.',
|
||||
'default' => '',
|
||||
'example' => '620 Eighth Avenue, New York, NY 10018',
|
||||
])
|
||||
->addRule('legalTaxId', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Company Tax ID.',
|
||||
'default' => '',
|
||||
'example' => '131102020',
|
||||
])
|
||||
->addRule('authDuration', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Session duration in seconds.',
|
||||
'default' => TOKEN_EXPIRATION_LOGIN_LONG,
|
||||
'example' => 60,
|
||||
])
|
||||
->addRule('authLimit', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Max users allowed. 0 is unlimited.',
|
||||
'default' => 0,
|
||||
'example' => 100,
|
||||
])
|
||||
->addRule('authSessionsLimit', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Max sessions allowed per user. 100 maximum.',
|
||||
'default' => 10,
|
||||
'example' => 10,
|
||||
])
|
||||
->addRule('authPasswordHistory', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Max allowed passwords in the history list per user. Max passwords limit allowed in history is 20. Use 0 for disabling password history.',
|
||||
'default' => 0,
|
||||
'example' => 5,
|
||||
])
|
||||
->addRule('authPasswordDictionary', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to check user\'s password against most commonly used passwords.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authPersonalDataCheck', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to check the user password for similarity with their personal data.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authDisposableEmails', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to disallow disposable email addresses during signup and email updates.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authCanonicalEmails', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to require canonical email addresses during signup and email updates.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authFreeEmails', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to disallow free email addresses during signup and email updates.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMockNumbers', [
|
||||
'type' => Response::MODEL_MOCK_NUMBER,
|
||||
'description' => 'An array of mock numbers and their corresponding verification codes (OTPs).',
|
||||
'default' => [],
|
||||
'array' => true,
|
||||
'example' => [new \stdClass()],
|
||||
])
|
||||
->addRule('authSessionAlerts', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to send session alert emails to users.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserName', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user names in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserEmail', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user emails in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsMfa', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user MFA status in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserId', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user IDs in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserPhone', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user phone numbers in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authInvalidateSessions', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not all existing sessions should be invalidated on password change',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('oAuthProviders', [
|
||||
'type' => Response::MODEL_AUTH_PROVIDER,
|
||||
'description' => 'List of Auth Providers.',
|
||||
'default' => [],
|
||||
'example' => [new \stdClass()],
|
||||
'array' => true,
|
||||
])
|
||||
->addRule('platforms', [
|
||||
'type' => [
|
||||
Response::MODEL_PLATFORM_WEB,
|
||||
Response::MODEL_PLATFORM_APPLE,
|
||||
Response::MODEL_PLATFORM_ANDROID,
|
||||
Response::MODEL_PLATFORM_WINDOWS,
|
||||
Response::MODEL_PLATFORM_LINUX,
|
||||
],
|
||||
'description' => 'List of Platforms.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
->addRule('webhooks', [
|
||||
'type' => Response::MODEL_WEBHOOK,
|
||||
'description' => 'List of Webhooks.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
->addRule('keys', [
|
||||
'type' => Response::MODEL_KEY,
|
||||
'description' => 'List of API Keys.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
|
||||
// Resource: Dev Keys
|
||||
->addRule('devKeys', [
|
||||
'type' => Response::MODEL_DEV_KEY,
|
||||
'description' => 'List of dev keys.',
|
||||
'description' => 'Deprecated since 1.9.5: List of dev keys.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
|
||||
// Resource: SMTP
|
||||
->addRule('smtpEnabled', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Status for custom SMTP',
|
||||
@@ -301,6 +115,8 @@ class Project extends Model
|
||||
'default' => '',
|
||||
'example' => 'tls',
|
||||
])
|
||||
|
||||
// Resource: Ping
|
||||
->addRule('pingCount', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Number of times the ping was received for this project.',
|
||||
@@ -313,6 +129,8 @@ class Project extends Model
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
|
||||
// Resource: Labels
|
||||
->addRule('labels', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Labels for the project.',
|
||||
@@ -320,64 +138,42 @@ class Project extends Model
|
||||
'example' => ['vip'],
|
||||
'array' => true,
|
||||
])
|
||||
|
||||
// Resource: Billing
|
||||
->addRule('status', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Project status.',
|
||||
'default' => 'active',
|
||||
'example' => 'active',
|
||||
])
|
||||
|
||||
// Resource: Auth methods
|
||||
->addRule('authMethods', [
|
||||
'type' => Response::MODEL_PROJECT_AUTH_METHOD,
|
||||
'description' => 'List of auth methods.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
|
||||
// Resource: Services
|
||||
->addRule('services', [
|
||||
'type' => Response::MODEL_PROJECT_SERVICE,
|
||||
'description' => 'List of services.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
|
||||
// Resource: Protocols
|
||||
->addRule('protocols', [
|
||||
'type' => Response::MODEL_PROJECT_PROTOCOL,
|
||||
'description' => 'List of protocols.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'array' => true,
|
||||
])
|
||||
;
|
||||
|
||||
$services = Config::getParam('services', []);
|
||||
$auth = Config::getParam('auth', []);
|
||||
|
||||
foreach ($auth as $index => $method) {
|
||||
$name = $method['name'] ?? '';
|
||||
$key = $method['key'] ?? '';
|
||||
|
||||
$this
|
||||
->addRule('auth' . ucfirst($key), [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => $name . ' auth method status',
|
||||
'example' => true,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
foreach ($services as $service) {
|
||||
if (!$service['optional']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $service['name'] ?? '';
|
||||
$key = $service['key'] ?? '';
|
||||
|
||||
$this
|
||||
->addRule('serviceStatusFor' . ucfirst($key), [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => $name . ' service status',
|
||||
'example' => true,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
$apis = Config::getParam('protocols', []);
|
||||
|
||||
foreach ($apis as $api) {
|
||||
$name = $api['name'] ?? '';
|
||||
$key = $api['key'] ?? '';
|
||||
|
||||
$this
|
||||
->addRule('protocolStatusFor' . ucfirst($key), [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => $name . ' protocol status',
|
||||
'example' => true,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,10 +204,9 @@ class Project extends Model
|
||||
public function filter(Document $document): Document
|
||||
{
|
||||
$this->expandSmtpFields($document);
|
||||
$this->expandServiceFields($document);
|
||||
$this->expandApiFields($document);
|
||||
$this->expandAuthFields($document);
|
||||
$this->expandOAuthProviders($document);
|
||||
$this->expandServices($document);
|
||||
$this->expandProtocols($document);
|
||||
$this->expandAuthMethods($document);
|
||||
|
||||
return $document;
|
||||
}
|
||||
@@ -422,8 +217,8 @@ class Project extends Model
|
||||
return;
|
||||
}
|
||||
|
||||
// SMTP
|
||||
$smtp = $document->getAttribute('smtp', []);
|
||||
|
||||
$document->setAttribute('smtpEnabled', $smtp['enabled'] ?? false);
|
||||
$document->setAttribute('smtpSenderEmail', $smtp['senderEmail'] ?? '');
|
||||
$document->setAttribute('smtpSenderName', $smtp['senderName'] ?? '');
|
||||
@@ -436,100 +231,52 @@ class Project extends Model
|
||||
$document->setAttribute('smtpSecure', $smtp['secure'] ?? '');
|
||||
}
|
||||
|
||||
private function expandServiceFields(Document $document): void
|
||||
private function expandServices(Document $document): void
|
||||
{
|
||||
if (!$document->isSet('services')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$values = $document->getAttribute('services', []);
|
||||
$services = Config::getParam('services', []);
|
||||
$services = [];
|
||||
|
||||
foreach ($services as $service) {
|
||||
foreach (Config::getParam('services', []) as $id => $service) {
|
||||
if (!$service['optional']) {
|
||||
continue;
|
||||
}
|
||||
$key = $service['key'] ?? '';
|
||||
$value = $values[$key] ?? true;
|
||||
$document->setAttribute('serviceStatusFor' . ucfirst($key), $value);
|
||||
}
|
||||
}
|
||||
|
||||
private function expandApiFields(Document $document): void
|
||||
{
|
||||
if (!$document->isSet('apis')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$values = $document->getAttribute('apis', []);
|
||||
$apis = Config::getParam('protocols', []);
|
||||
|
||||
foreach ($apis as $api) {
|
||||
$key = $api['key'] ?? '';
|
||||
$value = $values[$key] ?? true;
|
||||
$document->setAttribute('protocolStatusFor' . ucfirst($key), $value);
|
||||
}
|
||||
}
|
||||
|
||||
private function expandAuthFields(Document $document): void
|
||||
{
|
||||
if (!$document->isSet('auths')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$authValues = $document->getAttribute('auths', []);
|
||||
$auth = Config::getParam('auth', []);
|
||||
|
||||
$document->setAttribute('authLimit', $authValues['limit'] ?? 0);
|
||||
$document->setAttribute('authDuration', $authValues['duration'] ?? TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$document->setAttribute('authSessionsLimit', $authValues['maxSessions'] ?? 0);
|
||||
$document->setAttribute('authPasswordHistory', $authValues['passwordHistory'] ?? 0);
|
||||
$document->setAttribute('authPasswordDictionary', $authValues['passwordDictionary'] ?? false);
|
||||
$document->setAttribute('authPersonalDataCheck', $authValues['personalDataCheck'] ?? false);
|
||||
$document->setAttribute('authDisposableEmails', $authValues['disposableEmails'] ?? false);
|
||||
$document->setAttribute('authCanonicalEmails', $authValues['canonicalEmails'] ?? false);
|
||||
$document->setAttribute('authFreeEmails', $authValues['freeEmails'] ?? false);
|
||||
$document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? []);
|
||||
$document->setAttribute('authSessionAlerts', $authValues['sessionAlerts'] ?? false);
|
||||
$document->setAttribute('authMembershipsUserName', $authValues['membershipsUserName'] ?? false);
|
||||
$document->setAttribute('authMembershipsUserEmail', $authValues['membershipsUserEmail'] ?? false);
|
||||
$document->setAttribute('authMembershipsMfa', $authValues['membershipsMfa'] ?? false);
|
||||
$document->setAttribute('authMembershipsUserId', $authValues['membershipsUserId'] ?? false);
|
||||
$document->setAttribute('authMembershipsUserPhone', $authValues['membershipsUserPhone'] ?? false);
|
||||
$document->setAttribute('authInvalidateSessions', $authValues['invalidateSessions'] ?? false);
|
||||
|
||||
foreach ($auth as $method) {
|
||||
$key = $method['key'];
|
||||
$value = $authValues[$key] ?? true;
|
||||
$document->setAttribute('auth' . ucfirst($key), $value);
|
||||
}
|
||||
}
|
||||
|
||||
private function expandOAuthProviders(Document $document): void
|
||||
{
|
||||
if (!$document->isSet('oAuthProviders')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$providers = Config::getParam('oAuthProviders', []);
|
||||
$providerValues = $document->getAttribute('oAuthProviders', []);
|
||||
$projectProviders = [];
|
||||
|
||||
foreach ($providers as $key => $provider) {
|
||||
if (!$provider['enabled']) {
|
||||
// Disabled by Appwrite configuration, exclude from response
|
||||
continue;
|
||||
}
|
||||
|
||||
$projectProviders[] = new Document([
|
||||
'key' => $key,
|
||||
'name' => $provider['name'] ?? '',
|
||||
'appId' => $providerValues[$key . 'Appid'] ?? '',
|
||||
'secret' => '', // Write-only: never expose the stored value
|
||||
'enabled' => $providerValues[$key . 'Enabled'] ?? false,
|
||||
$services[] = new Document([
|
||||
'$id' => $id,
|
||||
'enabled' => $values[$service['key']] ?? true,
|
||||
]);
|
||||
}
|
||||
|
||||
$document->setAttribute('oAuthProviders', $projectProviders);
|
||||
$document->setAttribute('services', $services);
|
||||
}
|
||||
|
||||
private function expandProtocols(Document $document): void
|
||||
{
|
||||
$values = $document->getAttribute('apis', []);
|
||||
$protocols = [];
|
||||
|
||||
foreach (Config::getParam('protocols', []) as $id => $api) {
|
||||
$protocols[] = new Document([
|
||||
'$id' => $id,
|
||||
'enabled' => $values[$api['key']] ?? true,
|
||||
]);
|
||||
}
|
||||
|
||||
$document->setAttribute('protocols', $protocols);
|
||||
}
|
||||
|
||||
private function expandAuthMethods(Document $document): void
|
||||
{
|
||||
$values = $document->getAttribute('auths', []);
|
||||
$authMethods = [];
|
||||
|
||||
foreach (Config::getParam('auth', []) as $id => $method) {
|
||||
$authMethods[] = new Document([
|
||||
'$id' => $id,
|
||||
'enabled' => $values[$method['key']] ?? true
|
||||
]);
|
||||
}
|
||||
|
||||
$document->setAttribute('authMethods', $authMethods);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
class ProjectAuthMethod extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_ENUM,
|
||||
'description' => 'Auth method ID.',
|
||||
'default' => '',
|
||||
'example' => 'email-password',
|
||||
'enum' => \array_keys(Config::getParam('auth', [])),
|
||||
])
|
||||
->addRule('enabled', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Auth method status.',
|
||||
'example' => false,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ProjectAuthMethod';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_PROJECT_AUTH_METHOD;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
class ProjectProtocol extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_ENUM,
|
||||
'description' => 'Protocol ID.',
|
||||
'default' => '',
|
||||
'example' => 'graphql',
|
||||
'enum' => \array_keys(Config::getParam('protocols', [])),
|
||||
])
|
||||
->addRule('enabled', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Protocol status.',
|
||||
'example' => false,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ProjectProtocol';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_PROJECT_PROTOCOL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
class ProjectService extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_ENUM,
|
||||
'description' => 'Service ID.',
|
||||
'default' => '',
|
||||
'example' => 'sites',
|
||||
'enum' => \array_keys(\array_filter(Config::getParam('services', []), fn ($element) => $element['optional'])),
|
||||
])
|
||||
->addRule('enabled', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Service status.',
|
||||
'example' => false,
|
||||
'default' => true,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ProjectService';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_PROJECT_SERVICE;
|
||||
}
|
||||
}
|
||||
@@ -212,6 +212,7 @@ trait AuthMethodsBase
|
||||
$headers = \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders());
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
@@ -322,7 +323,9 @@ trait AuthMethodsBase
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = \array_merge($headers, $this->getHeaders());
|
||||
$headers = \array_merge($headers, $this->getHeaders(), [
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->client->call(
|
||||
|
||||
@@ -28,6 +28,7 @@ class OAuthGitHubIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
// Step 1: Create new organization (team)
|
||||
|
||||
@@ -1082,7 +1082,9 @@ trait PoliciesBase
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
$headers = array_merge($headers, $this->getHeaders(), [
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
]);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
@@ -1094,6 +1096,7 @@ trait PoliciesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesMembershipPrivacyIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
// Step 1: Configure privacy to false
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesPasswordDictionaryIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
// "password" is the top entry in the common-passwords dictionary and is 8 chars (min length).
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesPasswordHistoryIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
// Step 1: Enable password history policy with limit 3
|
||||
|
||||
@@ -21,6 +21,7 @@ class PoliciesPasswordPersonalDataIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
$setPersonalData = function (bool $enabled) use ($serverHeaders): void {
|
||||
|
||||
@@ -23,6 +23,7 @@ class PoliciesSessionAlertIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
$publicHeaders = [
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesSessionDurationIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
$publicHeaders = [
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesSessionInvalidationIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
$publicHeaders = [
|
||||
|
||||
@@ -22,6 +22,7 @@ class PoliciesUserLimitIntegrationTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apiKey,
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
];
|
||||
|
||||
$signupHeaders = [
|
||||
|
||||
@@ -51,6 +51,88 @@ class ProjectConsoleClientTest extends Scope
|
||||
$this->assertSame(404, $getProject['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testGetProject(): void
|
||||
{
|
||||
$team = $this->createTeam('Get Project Team');
|
||||
$project = $this->createProject($team['body']['$id'], 'Get Project');
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/project', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project['body']['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertSame(200, $response['headers']['status-code']);
|
||||
$this->assertSame($project['body']['$id'], $response['body']['$id']);
|
||||
$this->assertNotEmpty($response['body']['$createdAt']);
|
||||
$this->assertNotEmpty($response['body']['$updatedAt']);
|
||||
$this->assertSame('Get Project', $response['body']['name']);
|
||||
$this->assertSame($team['body']['$id'], $response['body']['teamId']);
|
||||
$this->assertSame('active', $response['body']['status']);
|
||||
|
||||
// Auth methods
|
||||
$this->assertIsArray($response['body']['authMethods']);
|
||||
$this->assertNotEmpty($response['body']['authMethods']);
|
||||
foreach ($response['body']['authMethods'] as $authMethod) {
|
||||
$this->assertArrayHasKey('$id', $authMethod);
|
||||
$this->assertArrayHasKey('enabled', $authMethod);
|
||||
$this->assertIsBool($authMethod['enabled']);
|
||||
}
|
||||
|
||||
// Services
|
||||
$this->assertIsArray($response['body']['services']);
|
||||
$this->assertNotEmpty($response['body']['services']);
|
||||
foreach ($response['body']['services'] as $service) {
|
||||
$this->assertArrayHasKey('$id', $service);
|
||||
$this->assertArrayHasKey('enabled', $service);
|
||||
$this->assertIsBool($service['enabled']);
|
||||
}
|
||||
|
||||
// Protocols
|
||||
$this->assertIsArray($response['body']['protocols']);
|
||||
$this->assertNotEmpty($response['body']['protocols']);
|
||||
foreach ($response['body']['protocols'] as $protocol) {
|
||||
$this->assertArrayHasKey('$id', $protocol);
|
||||
$this->assertArrayHasKey('enabled', $protocol);
|
||||
$this->assertIsBool($protocol['enabled']);
|
||||
}
|
||||
|
||||
// SMTP defaults
|
||||
$this->assertFalse($response['body']['smtpEnabled']);
|
||||
$this->assertSame('', $response['body']['smtpSenderEmail']);
|
||||
$this->assertSame('', $response['body']['smtpSenderName']);
|
||||
$this->assertSame('', $response['body']['smtpReplyToEmail']);
|
||||
$this->assertSame('', $response['body']['smtpReplyToName']);
|
||||
$this->assertSame('', $response['body']['smtpHost']);
|
||||
$this->assertSame('', $response['body']['smtpPort']);
|
||||
$this->assertSame('', $response['body']['smtpUsername']);
|
||||
$this->assertSame('', $response['body']['smtpPassword']);
|
||||
$this->assertSame('', $response['body']['smtpSecure']);
|
||||
|
||||
// Other fields
|
||||
$this->assertIsArray($response['body']['labels']);
|
||||
$this->assertIsArray($response['body']['devKeys']);
|
||||
$this->assertSame(0, $response['body']['pingCount']);
|
||||
$this->assertSame('', $response['body']['pingedAt']);
|
||||
|
||||
// Ensure old flattened fields are not present
|
||||
$this->assertArrayNotHasKey('description', $response['body']);
|
||||
$this->assertArrayNotHasKey('logo', $response['body']);
|
||||
$this->assertArrayNotHasKey('url', $response['body']);
|
||||
$this->assertArrayNotHasKey('authDuration', $response['body']);
|
||||
$this->assertArrayNotHasKey('authLimit', $response['body']);
|
||||
$this->assertArrayNotHasKey('authSessionsLimit', $response['body']);
|
||||
$this->assertArrayNotHasKey('authPasswordHistory', $response['body']);
|
||||
$this->assertArrayNotHasKey('authPasswordDictionary', $response['body']);
|
||||
$this->assertArrayNotHasKey('authPersonalDataCheck', $response['body']);
|
||||
$this->assertArrayNotHasKey('authDisposableEmails', $response['body']);
|
||||
$this->assertArrayNotHasKey('authCanonicalEmails', $response['body']);
|
||||
$this->assertArrayNotHasKey('authFreeEmails', $response['body']);
|
||||
$this->assertArrayNotHasKey('oAuthProviders', $response['body']);
|
||||
$this->assertArrayNotHasKey('platforms', $response['body']);
|
||||
$this->assertArrayNotHasKey('webhooks', $response['body']);
|
||||
$this->assertArrayNotHasKey('keys', $response['body']);
|
||||
}
|
||||
|
||||
protected function createTeam(string $name): array
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_POST, '/teams', $this->getConsoleSessionHeaders(), [
|
||||
|
||||
@@ -248,6 +248,7 @@ trait ProtocolsBase
|
||||
$headers = array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders());
|
||||
|
||||
// Disable via the legacy `/status` alias
|
||||
@@ -278,7 +279,9 @@ trait ProtocolsBase
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
$headers = array_merge($headers, $this->getHeaders(), [
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->client->call(Client::METHOD_PATCH, '/project/protocols/' . $protocolId, $headers, [
|
||||
|
||||
@@ -246,6 +246,7 @@ trait ServicesBase
|
||||
$headers = array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders());
|
||||
|
||||
// Disable via the legacy `/status` alias
|
||||
@@ -276,7 +277,9 @@ trait ServicesBase
|
||||
];
|
||||
|
||||
if ($authenticated) {
|
||||
$headers = array_merge($headers, $this->getHeaders());
|
||||
$headers = array_merge($headers, $this->getHeaders(), [
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->client->call(Client::METHOD_PATCH, '/project/services/' . $serviceId, $headers, [
|
||||
|
||||
@@ -46,6 +46,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4'
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -68,6 +69,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -89,6 +91,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => '',
|
||||
@@ -101,6 +104,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -127,6 +131,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'MultiDB Project',
|
||||
@@ -210,6 +215,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$getProject = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(404, $getProject['headers']['status-code']);
|
||||
@@ -234,6 +240,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => $projectId,
|
||||
'name' => 'Original Project',
|
||||
@@ -249,6 +256,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => $projectId,
|
||||
'name' => 'Project Duplicate',
|
||||
@@ -298,6 +306,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Team 1 Project',
|
||||
@@ -318,6 +327,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/team', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'teamId' => $team2,
|
||||
]);
|
||||
@@ -341,6 +351,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -353,6 +364,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders(), [
|
||||
'search' => $id
|
||||
]));
|
||||
@@ -364,6 +376,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders(), [
|
||||
'search' => 'Project Test'
|
||||
]));
|
||||
@@ -390,6 +403,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test 2',
|
||||
@@ -408,6 +422,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('teamId', [$team['body']['$id']])->toString(),
|
||||
@@ -422,6 +437,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
@@ -435,6 +451,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
@@ -447,6 +464,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('name', ['Project Test 2'])->toString(),
|
||||
@@ -461,6 +479,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::orderDesc()->toString(),
|
||||
@@ -474,6 +493,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -483,6 +503,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
|
||||
@@ -498,6 +519,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
@@ -524,6 +546,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Query Select Test Project',
|
||||
@@ -540,6 +563,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name'])->toString(),
|
||||
@@ -569,6 +593,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4'
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'teamId', 'description', '$createdAt', '$updatedAt'])->toString(),
|
||||
@@ -600,6 +625,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'teamId'])->toString(),
|
||||
@@ -631,6 +657,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name'])->toString(),
|
||||
@@ -661,6 +688,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'platforms'])->toString(),
|
||||
@@ -690,6 +718,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'name', 'webhooks', 'keys'])->toString(),
|
||||
@@ -719,6 +748,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['*'])->toString(),
|
||||
@@ -749,6 +779,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::select(['$id', 'invalidAttribute'])->toString(),
|
||||
@@ -783,6 +814,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -1027,6 +1059,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -1041,17 +1074,17 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$this->assertNotEmpty($response['body']['$updatedAt']);
|
||||
$this->assertNotFalse(\strtotime($response['body']['$updatedAt']));
|
||||
|
||||
$this->assertEquals('My description', $response['body']['description']);
|
||||
// $this->assertEquals('My description', $response['body']['description']); // No longer supported
|
||||
$this->assertEquals($team['body']['$id'], $response['body']['teamId']);
|
||||
$this->assertEquals('active', $response['body']['status']);
|
||||
$this->assertEquals('https://google.com/logo.png', $response['body']['logo']);
|
||||
$this->assertEquals('https://myapp.com/', $response['body']['url']);
|
||||
$this->assertEquals('Legal company', $response['body']['legalName']);
|
||||
$this->assertEquals('Slovakia', $response['body']['legalCountry']);
|
||||
$this->assertEquals('Custom state', $response['body']['legalState']);
|
||||
$this->assertEquals('Košice', $response['body']['legalCity']);
|
||||
$this->assertEquals('Main street 32', $response['body']['legalAddress']);
|
||||
$this->assertEquals('TAXID_123456', $response['body']['legalTaxId']);
|
||||
// $this->assertEquals('https://google.com/logo.png', $response['body']['logo']); // No longer supported
|
||||
// $this->assertEquals('https://myapp.com/', $response['body']['url']); // No longer supported
|
||||
// $this->assertEquals('Legal company', $response['body']['legalName']); // No longer supported
|
||||
// $this->assertEquals('Slovakia', $response['body']['legalCountry']); // No longer supported
|
||||
// $this->assertEquals('Custom state', $response['body']['legalState']); // No longer supported
|
||||
// $this->assertEquals('Košice', $response['body']['legalCity']); // No longer supported
|
||||
// $this->assertEquals('Main street 32', $response['body']['legalAddress']); // No longer supported
|
||||
// $this->assertEquals('TAXID_123456', $response['body']['legalTaxId']); // No longer supported
|
||||
$this->assertEquals(135, $response['body']['authDuration']);
|
||||
$this->assertEquals(54, $response['body']['authLimit']);
|
||||
$this->assertEquals(7, $response['body']['authSessionsLimit']);
|
||||
@@ -1411,6 +1444,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -1482,6 +1516,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/empty', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
@@ -1490,9 +1525,10 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/'.$projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testGetProjectUsage(): void
|
||||
@@ -1520,6 +1556,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -1536,6 +1573,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test 2',
|
||||
@@ -1556,6 +1594,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => '',
|
||||
@@ -1580,6 +1619,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'enabled' => true,
|
||||
'senderEmail' => 'mailer@appwrite.io',
|
||||
@@ -1605,6 +1645,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -1624,6 +1665,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/smtp', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'enabled' => true,
|
||||
'senderEmail' => 'fail@appwrite.io',
|
||||
@@ -1663,6 +1705,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -1851,6 +1894,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Session Alert Locale Fallback Test',
|
||||
@@ -1864,6 +1908,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/smtp', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'enabled' => true,
|
||||
'senderEmail' => 'mailer@appwrite.io',
|
||||
@@ -1932,6 +1977,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertTrue($response['body']['authSessionAlerts']);
|
||||
@@ -2054,6 +2100,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2166,6 +2213,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2189,6 +2237,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Session Invalidation Test Project',
|
||||
@@ -2203,6 +2252,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2220,6 +2270,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2237,6 +2288,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2261,6 +2313,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -2280,6 +2333,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'provider' => $key,
|
||||
'appId' => 'AppId-' . ucfirst($key),
|
||||
@@ -2293,6 +2347,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2320,6 +2375,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'provider' => $key,
|
||||
'enabled' => $i === 0 ? false : true // On first provider, test enabled=false
|
||||
@@ -2334,6 +2390,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2363,6 +2420,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'provider' => 'unknown',
|
||||
'appId' => 'AppId',
|
||||
@@ -2390,6 +2448,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
@@ -2445,6 +2504,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -2855,6 +2915,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -2864,6 +2925,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
'phone' => '+1655513432',
|
||||
@@ -2877,6 +2939,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2892,6 +2955,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2907,6 +2971,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2922,6 +2987,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2937,6 +3003,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2952,6 +3019,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -2979,6 +3047,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => $numbers
|
||||
]);
|
||||
@@ -2992,6 +3061,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => []
|
||||
]);
|
||||
@@ -3000,6 +3070,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'numbers' => [
|
||||
[
|
||||
@@ -3323,6 +3394,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]), [
|
||||
'projectId' => ID::unique(),
|
||||
@@ -3358,6 +3430,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3387,6 +3460,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3412,6 +3486,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]), [
|
||||
'projectId' => ID::unique(),
|
||||
@@ -3442,6 +3517,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3464,6 +3540,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3487,6 +3564,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]), [
|
||||
'projectId' => ID::unique(),
|
||||
@@ -3527,6 +3605,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3603,6 +3682,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -3679,6 +3759,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
|
||||
]));
|
||||
|
||||
@@ -4437,6 +4518,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test 2',
|
||||
@@ -5485,6 +5567,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
@@ -5510,6 +5593,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $project['headers']['status-code']);
|
||||
@@ -5533,6 +5617,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(404, $project['headers']['status-code']);
|
||||
@@ -5556,6 +5641,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project 1',
|
||||
@@ -5566,6 +5652,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project 2',
|
||||
@@ -6908,6 +6995,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Test project - Labels 1',
|
||||
@@ -6952,6 +7040,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['nonvip'])->toString(),
|
||||
@@ -6964,6 +7053,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['vip'])->toString(),
|
||||
@@ -6975,6 +7065,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['imagine'])->toString(),
|
||||
@@ -6987,6 +7078,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['nonvip', 'imagine'])->toString(),
|
||||
@@ -7000,6 +7092,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Test project - Labels 2',
|
||||
@@ -7028,6 +7121,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['imagine'])->toString(),
|
||||
@@ -7042,6 +7136,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['vip'])->toString(),
|
||||
@@ -7055,6 +7150,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['vip'])->toString(),
|
||||
@@ -7069,6 +7165,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$projects = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::contains('labels', ['vip', 'imagine'])->toString(),
|
||||
@@ -7174,6 +7271,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
|
||||
]);
|
||||
|
||||
@@ -7270,6 +7368,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
|
||||
], [
|
||||
'name' => $newProjectName,
|
||||
@@ -7286,6 +7385,7 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-response-format' => '1.9.4',
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $token,
|
||||
], [
|
||||
'name' => $newProjectName,
|
||||
|
||||
@@ -2633,6 +2633,7 @@ class SitesCustomServerTest extends Scope
|
||||
|
||||
// Poll for execution logs to be written (async)
|
||||
// Filter by requestPath to avoid picking up screenshot worker executions
|
||||
// Wait for both the execution entry AND its logs field to be populated
|
||||
$logs = null;
|
||||
$timeout = 120;
|
||||
$start = \time();
|
||||
@@ -2642,12 +2643,13 @@ class SitesCustomServerTest extends Scope
|
||||
Query::equal('requestPath', ['/logs-inline'])->toString(),
|
||||
Query::limit(1)->toString(),
|
||||
]);
|
||||
if (!empty($logs['body']['executions'])) {
|
||||
if (!empty($logs['body']['executions']) && !empty($logs['body']['executions'][0]['logs'])) {
|
||||
break;
|
||||
}
|
||||
\usleep(500000);
|
||||
}
|
||||
$this->assertNotEmpty($logs['body']['executions'], 'Execution logs were not available within timeout');
|
||||
$this->assertNotNull($logs['body']['executions'][0]['logs'], 'Execution logs content was not populated within timeout');
|
||||
$this->assertEquals(200, $logs['headers']['status-code']);
|
||||
$this->assertStringContainsString($deploymentId, $logs['body']['executions'][0]['deploymentId']);
|
||||
$this->assertStringContainsString("GET", $logs['body']['executions'][0]['requestMethod']);
|
||||
@@ -2681,11 +2683,21 @@ class SitesCustomServerTest extends Scope
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertStringContainsString("Action logs printed.", $response['body']);
|
||||
|
||||
$logs = $this->listLogs($siteId, [
|
||||
Query::orderDesc('$createdAt')->toString(),
|
||||
Query::equal('requestPath', ['/logs-action'])->toString(),
|
||||
Query::limit(1)->toString(),
|
||||
]);
|
||||
$logs = null;
|
||||
$start = \time();
|
||||
while (\time() - $start < $timeout) {
|
||||
$logs = $this->listLogs($siteId, [
|
||||
Query::orderDesc('$createdAt')->toString(),
|
||||
Query::equal('requestPath', ['/logs-action'])->toString(),
|
||||
Query::limit(1)->toString(),
|
||||
]);
|
||||
if (!empty($logs['body']['executions']) && !empty($logs['body']['executions'][0]['logs'])) {
|
||||
break;
|
||||
}
|
||||
\usleep(500000);
|
||||
}
|
||||
$this->assertNotEmpty($logs['body']['executions'], 'Action execution logs were not available within timeout');
|
||||
$this->assertNotNull($logs['body']['executions'][0]['logs'], 'Action execution logs content was not populated within timeout');
|
||||
$this->assertEquals(200, $logs['headers']['status-code']);
|
||||
$this->assertStringContainsString($deploymentId, $logs['body']['executions'][0]['deploymentId']);
|
||||
$this->assertStringContainsString("GET", $logs['body']['executions'][0]['requestMethod']);
|
||||
|
||||
@@ -34,10 +34,11 @@ class ResponseTest extends TestCase
|
||||
$this->assertTrue($this->response->hasFilters());
|
||||
$this->assertCount(2, $this->response->getFilters());
|
||||
|
||||
$output = $this->response->applyFilters([
|
||||
$content = [
|
||||
'initial' => true,
|
||||
'first' => false
|
||||
], 'test');
|
||||
];
|
||||
$output = $this->response->applyFilters($content, 'test', raw: new Document($content));
|
||||
|
||||
$this->assertArrayHasKey('initial', $output);
|
||||
$this->assertTrue($output['initial']);
|
||||
|
||||
Reference in New Issue
Block a user