From 7c5ed6ba5d759af51ee0530b927938bbda5418ed Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 00:05:22 +0530 Subject: [PATCH 1/8] Temp loggers --- .../RecoveryWarningNotificationCommand.php | 440 ++++++++++++------ 1 file changed, 293 insertions(+), 147 deletions(-) diff --git a/lib/Command/RecoveryWarningNotificationCommand.php b/lib/Command/RecoveryWarningNotificationCommand.php index b4120a7..1e8fa85 100644 --- a/lib/Command/RecoveryWarningNotificationCommand.php +++ b/lib/Command/RecoveryWarningNotificationCommand.php @@ -92,152 +92,253 @@ class RecoveryWarningNotificationCommand extends Command { ->addOption('test-mode', null, InputOption::VALUE_NONE, 'Enable test mode - process only limited number of users'); } - protected function execute(InputInterface $input, OutputInterface $output): int { - $disableAccounts = $input->getOption('disable-accounts'); - $deleteAccounts = $input->getOption('delete-accounts'); - $this->dryRun = $input->getOption('dry-run'); - $this->testMode = $input->getOption('test-mode'); +protected function execute(InputInterface $input, OutputInterface $output): int { + $overallStart = microtime(true); + $disableAccounts = $input->getOption('disable-accounts'); + $deleteAccounts = $input->getOption('delete-accounts'); + $this->dryRun = $input->getOption('dry-run'); + $this->testMode = $input->getOption('test-mode'); + + $output->writeln('[email-recovery] start'); + $output->writeln(' - disableAccounts=' . ((bool)$disableAccounts ? 'true' : 'false')); + $output->writeln(' - deleteAccounts=' . ((bool)$deleteAccounts ? 'true' : 'false')); + $output->writeln(' - dryRun=' . ($this->dryRun ? 'true' : 'false')); + $output->writeln(' - testMode=' . ($this->testMode ? 'true' : 'false')); + + if ($this->dryRun) { + $output->writeln('Running in DRY-RUN mode - no actual actions will be taken'); + } - if ($this->dryRun) { - $output->writeln('Running in DRY-RUN mode - no actual actions will be taken'); - } + if ($this->testMode) { + $output->writeln('Test mode enabled - processing only ' . $this->testModeUserLimit . ' users'); + } - if ($this->testMode) { - $output->writeln('Test mode enabled - processing only ' . $this->testModeUserLimit . ' users'); + try { + if (!$this->messageId) { + $output->writeln('Error: messageId not configured in recovery_warning_configs system configuration!'); + return Command::FAILURE; } - try { - if (!$this->messageId) { - $output->writeln('Error: messageId not configured in recovery_warning_configs system configuration!'); - return Command::FAILURE; - } - - // Initialize arrays - $this->uids = []; - $this->disableUids = []; - $this->deleteUids = []; - - // Process users - $this->identifyUnverifiedUsers($output); - $this->sendNotificationsAndEmails($output); + // Initialize arrays + $this->uids = []; + $this->disableUids = []; + $this->deleteUids = []; + + // Process users + $identifyStart = microtime(true); + $this->identifyUnverifiedUsers($output); + $output->writeln('[email-recovery] identifyUnverifiedUsers completed'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $identifyStart)); + $output->writeln(' - notifyCandidates=' . count($this->uids)); + $output->writeln(' - disableCandidates=' . count($this->disableUids)); + $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); + + $notifyStart = microtime(true); + $this->sendNotificationsAndEmails($output); + $output->writeln('[email-recovery] sendNotificationsAndEmails completed'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $notifyStart)); - if ($disableAccounts) { - $this->disableUnverifiedUsers($output); - } + if ($disableAccounts) { + $disableStart = microtime(true); + $this->disableUnverifiedUsers($output); + $output->writeln('[email-recovery] disableUnverifiedUsers completed'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $disableStart)); + $output->writeln(' - disableCandidates=' . count($this->disableUids)); + } - if ($deleteAccounts) { - $this->deleteExpiredDisabledUsers($output); - } - - $output->writeln('=== Command Summary ==='); - $output->writeln(' - Users for notifications: ' . count($this->uids)); - $output->writeln(' - Users for disable: ' . count($this->disableUids)); - $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); - - $output->writeln('Recovery warning notification command completed successfully.'); - return Command::SUCCESS; - } catch (\Throwable $e) { - $output->writeln('Error: ' . $e->getMessage() . ''); - return Command::FAILURE; + if ($deleteAccounts) { + $deleteStart = microtime(true); + $this->deleteExpiredDisabledUsers($output); + $output->writeln('[email-recovery] deleteExpiredDisabledUsers completed'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $deleteStart)); + $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); } + + $output->writeln('=== Command Summary ==='); + $output->writeln(' - Users for notifications: ' . count($this->uids)); + $output->writeln(' - Users for disable: ' . count($this->disableUids)); + $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); + + $overallDuration = microtime(true) - $overallStart; + $output->writeln('[email-recovery] completed'); + $output->writeln(' - overallDurationMs=' . $this->toMs($overallDuration)); + $output->writeln(' - notifyCandidates=' . count($this->uids)); + $output->writeln(' - disableCandidates=' . count($this->disableUids)); + $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); + $output->writeln('Recovery warning notification command completed successfully.'); + return Command::SUCCESS; + } catch (\Throwable $e) { + $output->writeln('Error: ' . $e->getMessage() . ''); + $output->writeln('[email-recovery] failed: ' . $e->getMessage() . ''); + return Command::FAILURE; } +} - private function identifyUnverifiedUsers(OutputInterface $output): void { - $users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', ''); - if (!is_array($users)) { - $output->writeln('Error: Expected array for recovery-email users, got ' . gettype($users) . ''); - return; - } +private function identifyUnverifiedUsers(OutputInterface $output): void { + $stageStart = microtime(true); + $users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', ''); + if (!is_array($users)) { + $output->writeln('Error: Expected array for recovery-email users, got ' . gettype($users) . ''); + return; + } - // Limit to user-limit for test mode - if ($this->testMode && count($users) > $this->testModeUserLimit) { - $users = array_slice($users, 0, $this->testModeUserLimit); - $output->writeln('Test mode: Limited to ' . $this->testModeUserLimit . ' users'); - } + // Limit to user-limit for test mode + if ($this->testMode && count($users) > $this->testModeUserLimit) { + $users = array_slice($users, 0, $this->testModeUserLimit); + $output->writeln('Test mode: Limited to ' . $this->testModeUserLimit . ' users'); + } - $processedCount = 0; - $skippedCount = 0; - $invalidCount = 0; - $errorCount = 0; + $processedCount = 0; + $skippedCount = 0; + $invalidCount = 0; + $errorCount = 0; - foreach ($users as $username) { - try { - $user = $this->userManager->get($username); - if (!$user) { - $invalidCount++; - continue; - } + // Aggregated timings (seconds) + $sumGetUser = 0.0; + $sumGetRecoveryEmail = 0.0; + $sumHasActiveSubscription = 0.0; + $sumConfigOps = 0.0; - if (!$this->isUserValid($user)) { - $invalidCount++; - continue; - } + foreach ($users as $username) { + try { + $userStart = microtime(true); + $t = microtime(true); + $user = $this->userManager->get($username); + $dtGetUser = microtime(true) - $t; + $sumGetUser += $dtGetUser; + if (!$user) { + $invalidCount++; + $output->writeln('[identify] user=' . $username . ' getUserMs=' . $this->toMs($dtGetUser) . ' invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; + } - $uid = $user->getUID(); - $emailAddress = $user->getEMailAddress(); + $t = microtime(true); + $isValid = $this->isUserValid($user); + $dtIsValid = microtime(true) - $t; + if (!$isValid) { + $invalidCount++; + $output->writeln('[identify] user=' . $username . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; + } - // Check if user has a VERIFIED recovery email - $verifiedRecoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); - if (!empty($verifiedRecoveryEmail)) { - $skippedCount++; - continue; - } + $uid = $user->getUID(); + $emailAddress = $user->getEMailAddress(); + + // Check if user has a VERIFIED recovery email + $t = microtime(true); + $verifiedRecoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); + $dtGetRecovery = microtime(true) - $t; + $sumGetRecoveryEmail += $dtGetRecovery; + if (!empty($verifiedRecoveryEmail)) { + $skippedCount++; + $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' skipped=verifiedRecoveryEmail totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; + } - // Check for active subscription - if ($this->recoveryEmailService->hasActiveSubscription($emailAddress)) { - $skippedCount++; - continue; - } + // Check for active subscription + $t = microtime(true); + $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); + $dtHasSub = microtime(true) - $t; + $sumHasActiveSubscription += $dtHasSub; + if ($hasSub) { + $skippedCount++; + $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; + } - // Get or set first run date - $firstRunDate = $this->config->getUserValue($uid, Application::APP_ID, 'first-run-date', null); - // Ensure firstRunDate is an integer timestamp - $firstRunDate = $firstRunDate ? (int)$firstRunDate : null; + // Get or set first run date + $tCfg = microtime(true); + $firstRunDate = $this->config->getUserValue($uid, Application::APP_ID, 'first-run-date', null); + // Ensure firstRunDate is an integer timestamp + $firstRunDate = $firstRunDate ? (int)$firstRunDate : null; - if ($firstRunDate === null) { - $firstRunDate = time(); - $this->config->setUserValue($uid, Application::APP_ID, 'first-run-date', $firstRunDate); - } + if ($firstRunDate === null) { + $firstRunDate = time(); + $this->config->setUserValue($uid, Application::APP_ID, 'first-run-date', $firstRunDate); + } + $dtFirstRunOps = microtime(true) - $tCfg; + $sumConfigOps += $dtFirstRunOps; - // Check if disable date is already set, if not set it - $existingDisableDate = $this->recoveryEmailService->getUnverifiedUserDisableAt($uid); + // Check if disable date is already set, if not set it + $tCfg = microtime(true); + $existingDisableDate = $this->recoveryEmailService->getUnverifiedUserDisableAt($uid); - if (empty($existingDisableDate)) { - // Set the disable date using config variable - $disableDate = date('Y-m-d', $firstRunDate + ($this->disableUserAfterUnverifiedDays * 24 * 60 * 60)); - $this->recoveryEmailService->setUnverifiedUserDisableAt($uid, $disableDate); - } + if (empty($existingDisableDate)) { + // Set the disable date using config variable + $disableDate = date('Y-m-d', $firstRunDate + ($this->disableUserAfterUnverifiedDays * 24 * 60 * 60)); + $this->recoveryEmailService->setUnverifiedUserDisableAt($uid, $disableDate); + } + $dtDisableOps = microtime(true) - $tCfg; + $sumConfigOps += $dtDisableOps; - // Calculate age and process - $age = (int) ((time() - $firstRunDate) / (24 * 60 * 60)); + // Calculate age and process + $age = (int) ((time() - $firstRunDate) / (24 * 60 * 60)); - if (in_array($age, $this->reminderDaysSinceStart)) { - $this->uids[] = $uid; - } - - $this->identifyForDisable($user, $age); - $this->identifyForDelete($user, $age); + if (in_array($age, $this->reminderDaysSinceStart)) { + $this->uids[] = $uid; + } - $processedCount++; - } catch (\Throwable $e) { - $errorCount++; - $output->writeln('Error processing user ' . $username . ': ' . $e->getMessage() . ''); - continue; + $t = microtime(true); + $this->identifyForDisable($user, $age); + $this->identifyForDelete($user, $age); + $dtFlags = microtime(true) - $t; + + $output->writeln('[identify] user=' . $uid + . ' getUserMs=' . $this->toMs($dtGetUser) + . ' isValidMs=' . $this->toMs($dtIsValid) + . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) + . ' hasSubMs=' . $this->toMs($dtHasSub) + . ' firstRunOpsMs=' . $this->toMs($dtFirstRunOps) + . ' disableOpsMs=' . $this->toMs($dtDisableOps) + . ' age=' . $age + . ' notify=' . (in_array($age, $this->reminderDaysSinceStart) ? '1' : '0') + . ' flagsMs=' . $this->toMs($dtFlags) + . ' totalMs=' . $this->toMs(microtime(true) - $userStart) + ); + + $processedCount++; + if ($processedCount % 1000 === 0) { + $elapsed = microtime(true) - $stageStart; + $output->writeln('[email-recovery] identify progress'); + $output->writeln(' - processed=' . $processedCount); + $output->writeln(' - elapsedMs=' . $this->toMs($elapsed)); + $output->writeln(' - rateUsersPerMin=' . (int)($processedCount / max($elapsed, 0.0001) * 60)); + $output->writeln(' - memoryMb=' . (int)(memory_get_usage(true) / 1024 / 1024)); } + } catch (\Throwable $e) { + $errorCount++; + $output->writeln('Error processing user ' . $username . ': ' . $e->getMessage() . ''); + $output->writeln('[email-recovery] Error processing user in identify for ' . $username . ': ' . $e->getMessage() . ''); + continue; } - - $output->writeln('User processing summary:'); - $output->writeln(' - Total users: ' . count($users)); - $output->writeln(' - Processed: ' . $processedCount); - $output->writeln(' - Skipped: ' . $skippedCount); - $output->writeln(' - Invalid: ' . $invalidCount); - $output->writeln(' - Errors: ' . $errorCount); - $output->writeln(' - For notifications: ' . count($this->uids)); - $output->writeln(' - For disable: ' . count($this->disableUids)); - $output->writeln(' - For deletion: ' . count($this->deleteUids)); } + + $output->writeln('User processing summary:'); + $output->writeln(' - Total users: ' . count($users)); + $output->writeln(' - Processed: ' . $processedCount); + $output->writeln(' - Skipped: ' . $skippedCount); + $output->writeln(' - Invalid: ' . $invalidCount); + $output->writeln(' - Errors: ' . $errorCount); + $output->writeln(' - For notifications: ' . count($this->uids)); + $output->writeln(' - For disable: ' . count($this->disableUids)); + $output->writeln(' - For deletion: ' . count($this->deleteUids)); + $output->writeln('[email-recovery] identifyUnverifiedUsers stats'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $stageStart)); + $output->writeln(' - totalUsers=' . count($users)); + $output->writeln(' - processed=' . $processedCount); + $output->writeln(' - skipped=' . $skippedCount); + $output->writeln(' - invalid=' . $invalidCount); + $output->writeln(' - errors=' . $errorCount); + $output->writeln(' - forNotifications=' . count($this->uids)); + $output->writeln(' - forDisable=' . count($this->disableUids)); + $output->writeln(' - forDeletion=' . count($this->deleteUids)); + $output->writeln(' - avgGetUserMs=' . ($processedCount ? $this->toMs($sumGetUser / $processedCount) : 0)); + $output->writeln(' - avgGetRecoveryEmailMs=' . ($processedCount ? $this->toMs($sumGetRecoveryEmail / $processedCount) : 0)); + $output->writeln(' - avgHasActiveSubscriptionMs=' . ($processedCount ? $this->toMs($sumHasActiveSubscription / $processedCount) : 0)); + $output->writeln(' - avgConfigOpsMs=' . ($processedCount ? $this->toMs($sumConfigOps / $processedCount) : 0)); +} private function identifyForDisable($user, int $age): void { if ($age >= $this->disableUserAfterUnverifiedDays) { @@ -266,10 +367,15 @@ class RecoveryWarningNotificationCommand extends Command { } $output->writeln('Sending notifications and emails to ' . count($this->uids) . ' users...'); + $output->writeln('[email-recovery] sendNotificationsAndEmails start'); + $output->writeln(' - users=' . count($this->uids)); + $stageStart = microtime(true); + $sumNotification = 0.0; + $sumEmail = 0.0; try { $notification = $this->prepareCloudNotification(); - $stats = $this->processUsersForNotificationsAndEmails($notification, $output); + $stats = $this->processUsersForNotificationsAndEmails($notification, $output, $sumNotification, $sumEmail); $output->writeln('Notification/Email summary:'); $output->writeln(' - Notifications sent: ' . $stats['notificationSentCount']); @@ -277,8 +383,18 @@ class RecoveryWarningNotificationCommand extends Command { $output->writeln(' - Emails sent: ' . $stats['emailSentCount']); $output->writeln(' - Emails failed: ' . $stats['emailFailedCount']); $output->writeln(' - No email address: ' . $stats['noEmailCount']); + $output->writeln('[email-recovery] sendNotificationsAndEmails stats'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $stageStart)); + $output->writeln(' - notificationsSent=' . $stats['notificationSentCount']); + $output->writeln(' - notificationsFailed=' . $stats['notificationFailedCount']); + $output->writeln(' - emailsSent=' . $stats['emailSentCount']); + $output->writeln(' - emailsFailed=' . $stats['emailFailedCount']); + $output->writeln(' - noEmail=' . $stats['noEmailCount']); + $output->writeln(' - avgNotifyMs=' . (($stats['notificationSentCount'] + $stats['notificationFailedCount']) ? $this->toMs($sumNotification / max(1, ($stats['notificationSentCount'] + $stats['notificationFailedCount']))) : 0)); + $output->writeln(' - avgEmailMs=' . (($stats['emailSentCount'] + $stats['emailFailedCount']) ? $this->toMs($sumEmail / max(1, ($stats['emailSentCount'] + $stats['emailFailedCount']))) : 0)); } catch (\Throwable $e) { $output->writeln('Error in sendNotificationsAndEmails: ' . $e->getMessage() . ''); + $output->writeln('[email-recovery] Error in sendNotificationsAndEmails: ' . $e->getMessage() . ''); } } @@ -295,41 +411,55 @@ class RecoveryWarningNotificationCommand extends Command { return $notification; } - private function processUsersForNotificationsAndEmails($notification, OutputInterface $output): array { - $stats = [ - 'notificationSentCount' => 0, - 'notificationFailedCount' => 0, - 'emailSentCount' => 0, - 'emailFailedCount' => 0, - 'noEmailCount' => 0 - ]; - - foreach ($this->uids as $uid) { - try { - $user = $this->userManager->get($uid); - if (!$user) { - $stats['notificationFailedCount']++; - $stats['emailFailedCount']++; - continue; - } - - $username = $user->getDisplayName(); - $emailAddress = $user->getEMailAddress(); - - // Send cloud notification - $this->sendNotificationToUserIfValid($user, $notification, $stats, $output); +private function processUsersForNotificationsAndEmails($notification, OutputInterface $output, float &$sumNotification, float &$sumEmail): array { + $stats = [ + 'notificationSentCount' => 0, + 'notificationFailedCount' => 0, + 'emailSentCount' => 0, + 'emailFailedCount' => 0, + 'noEmailCount' => 0 + ]; - // Send email - $this->sendEmailToUserIfValid($user, $emailAddress, $stats, $output); - } catch (\Throwable $e) { + foreach ($this->uids as $uid) { + try { + $userStart = microtime(true); + $user = $this->userManager->get($uid); + if (!$user) { $stats['notificationFailedCount']++; $stats['emailFailedCount']++; + $output->writeln('[notify] user=' . $uid . ' getUserMs=0 invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; } - } - return $stats; + $username = $user->getDisplayName(); + $emailAddress = $user->getEMailAddress(); + + // Send cloud notification + $t = microtime(true); + $this->sendNotificationToUserIfValid($user, $notification, $stats, $output); + $dtNotify = microtime(true) - $t; + $sumNotification += $dtNotify; + + // Send email + $t = microtime(true); + $this->sendEmailToUserIfValid($user, $emailAddress, $stats, $output); + $dtEmail = microtime(true) - $t; + $sumEmail += $dtEmail; + + $output->writeln('[notify] user=' . $uid + . ' notifyMs=' . $this->toMs($dtNotify) + . ' emailMs=' . $this->toMs($dtEmail) + . ' totalMs=' . $this->toMs(microtime(true) - $userStart) + ); + } catch (\Throwable $e) { + $stats['notificationFailedCount']++; + $stats['emailFailedCount']++; + } } + return $stats; +} + private function sendNotificationToUserIfValid($user, $notification, array &$stats, OutputInterface $output): void { $username = $user->getDisplayName(); @@ -450,6 +580,7 @@ class RecoveryWarningNotificationCommand extends Command { private function disableUnverifiedUsers(OutputInterface $output): void { $disabledCount = 0; $failedCount = 0; + $start = microtime(true); foreach ($this->disableUids as $uid) { try { @@ -473,11 +604,17 @@ class RecoveryWarningNotificationCommand extends Command { $failedCount++; } } + + $output->writeln('[email-recovery] disableUnverifiedUsers stats'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $start)); + $output->writeln(' - disabled=' . $disabledCount); + $output->writeln(' - failed=' . $failedCount); } private function deleteExpiredDisabledUsers(OutputInterface $output): void { $deletedCount = 0; $failedCount = 0; + $start = microtime(true); foreach ($this->deleteUids as $uid) { try { @@ -503,6 +640,11 @@ class RecoveryWarningNotificationCommand extends Command { $failedCount++; } } + + $output->writeln('[email-recovery] deleteExpiredDisabledUsers stats'); + $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $start)); + $output->writeln(' - deleted=' . $deletedCount); + $output->writeln(' - failed=' . $failedCount); } private function isUserValid($user): bool { @@ -513,4 +655,8 @@ class RecoveryWarningNotificationCommand extends Command { $emailAddress = $user->getEMailAddress(); return $emailAddress && $this->mailer->validateMailAddress($emailAddress); } + +private function toMs(float $seconds): int { + return (int) round($seconds * 1000); +} } -- GitLab From 2952b3ff9722f8dcfce581f19308ef72e2ec611f Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 00:08:32 +0530 Subject: [PATCH 2/8] gitlab --- .gitlab-ci.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9215688..ddd0278 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,3 +29,20 @@ include: ref: main file: "nc-publish-app.yml" + +deploy:staging: + extends: .deploy:nextcloud-app + rules: + - if: $CI_COMMIT_BRANCH == "main" + when: manual + - if: $CI_COMMIT_BRANCH == "murena-main" + when: manual + - if: $CI_COMMIT_BRANCH == "production" + when: manual + - if: $CI_COMMIT_BRANCH == "dev/temp-logger" + when: manual + - if: $CI_COMMIT_TAG + when: manual + environment: + name: staging/01 + url: $ENV_URL \ No newline at end of file -- GitLab From 5ae510f863e78919964ab9efbce7a4fe31de1a4e Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 00:24:08 +0530 Subject: [PATCH 3/8] hasActiveSub commented --- .../RecoveryWarningNotificationCommand.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/Command/RecoveryWarningNotificationCommand.php b/lib/Command/RecoveryWarningNotificationCommand.php index 1e8fa85..bae3edc 100644 --- a/lib/Command/RecoveryWarningNotificationCommand.php +++ b/lib/Command/RecoveryWarningNotificationCommand.php @@ -238,15 +238,17 @@ private function identifyUnverifiedUsers(OutputInterface $output): void { } // Check for active subscription - $t = microtime(true); - $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); - $dtHasSub = microtime(true) - $t; + // $t = microtime(true); + // $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); + // $dtHasSub = microtime(true) - $t; + // $sumHasActiveSubscription += $dtHasSub; + // if ($hasSub) { + // $skippedCount++; + // $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); + // continue; + // } + $dtHasSub = 0.0; $sumHasActiveSubscription += $dtHasSub; - if ($hasSub) { - $skippedCount++; - $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; - } // Get or set first run date $tCfg = microtime(true); -- GitLab From 2c5cca39d240b43e4efb0ed5e888feb9462e2ad7 Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 16:53:11 +0530 Subject: [PATCH 4/8] hasActive sub added --- .../RecoveryWarningNotificationCommand.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/Command/RecoveryWarningNotificationCommand.php b/lib/Command/RecoveryWarningNotificationCommand.php index bae3edc..1e8fa85 100644 --- a/lib/Command/RecoveryWarningNotificationCommand.php +++ b/lib/Command/RecoveryWarningNotificationCommand.php @@ -238,17 +238,15 @@ private function identifyUnverifiedUsers(OutputInterface $output): void { } // Check for active subscription - // $t = microtime(true); - // $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); - // $dtHasSub = microtime(true) - $t; - // $sumHasActiveSubscription += $dtHasSub; - // if ($hasSub) { - // $skippedCount++; - // $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); - // continue; - // } - $dtHasSub = 0.0; + $t = microtime(true); + $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); + $dtHasSub = microtime(true) - $t; $sumHasActiveSubscription += $dtHasSub; + if ($hasSub) { + $skippedCount++; + $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); + continue; + } // Get or set first run date $tCfg = microtime(true); -- GitLab From 4d4d024006bc9616d8184bcd9062d91b8628ceb4 Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 23:03:51 +0530 Subject: [PATCH 5/8] Fix deprecated annotations in EmailRecoveryController - Replace @NoAdminRequired annotations with #[NoAdminRequired] attributes - Replace @PublicPage annotations with #[PublicPage] attributes - Replace @NoCSRFRequired annotations with #[NoCSRFRequired] attributes - Add missing use statements for attribute classes - Fixes deprecation warnings in Nextcloud 31 --- lib/Controller/EmailRecoveryController.php | 25 ++++++++-------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/Controller/EmailRecoveryController.php b/lib/Controller/EmailRecoveryController.php index 54db943..0cb6c15 100644 --- a/lib/Controller/EmailRecoveryController.php +++ b/lib/Controller/EmailRecoveryController.php @@ -34,6 +34,9 @@ use OCA\EmailRecovery\Exception\SameRecoveryEmailAsEmailException; use OCA\EmailRecovery\Exception\TooManyVerificationAttemptsException; use OCA\EmailRecovery\Service\RecoveryEmailService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; @@ -71,10 +74,7 @@ class EmailRecoveryController extends Controller { $this->userManager = $userManager; } - /** - * @NoAdminRequired - */ - + #[NoAdminRequired] public function getRecoveryEmail() { $response = new JSONResponse(); $userId = $this->userSession->getUser()->getUID(); @@ -85,11 +85,9 @@ class EmailRecoveryController extends Controller { return $response; } - /** - * @NoAdminRequired - * @PublicPage - * @NoCSRFRequired - */ + #[NoAdminRequired] + #[PublicPage] + #[NoCSRFRequired] public function verifyRecoveryEmail(string $token, string $userId): TemplateResponse { try { //decrypt email @@ -126,10 +124,7 @@ class EmailRecoveryController extends Controller { } - /** - * @NoAdminRequired - */ - + #[NoAdminRequired] public function setRecoveryEmail(string $recoveryEmail) { $userId = $this->userSession->getUser()->getUID(); $response = new JSONResponse(); @@ -137,9 +132,7 @@ class EmailRecoveryController extends Controller { return $response; } - /** - * @NoAdminRequired - */ + #[NoAdminRequired] public function resendRecoveryEmail(string $recoveryEmail) { $response = new JSONResponse(); $response->setStatus(200); -- GitLab From be23e8f909b68c35cae77e2f6b4b23ec62339720 Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 23:07:21 +0530 Subject: [PATCH 6/8] reverted command --- .../RecoveryWarningNotificationCommand.php | 440 ++++++------------ 1 file changed, 147 insertions(+), 293 deletions(-) diff --git a/lib/Command/RecoveryWarningNotificationCommand.php b/lib/Command/RecoveryWarningNotificationCommand.php index 1e8fa85..b4120a7 100644 --- a/lib/Command/RecoveryWarningNotificationCommand.php +++ b/lib/Command/RecoveryWarningNotificationCommand.php @@ -92,253 +92,152 @@ class RecoveryWarningNotificationCommand extends Command { ->addOption('test-mode', null, InputOption::VALUE_NONE, 'Enable test mode - process only limited number of users'); } -protected function execute(InputInterface $input, OutputInterface $output): int { - $overallStart = microtime(true); - $disableAccounts = $input->getOption('disable-accounts'); - $deleteAccounts = $input->getOption('delete-accounts'); - $this->dryRun = $input->getOption('dry-run'); - $this->testMode = $input->getOption('test-mode'); - - $output->writeln('[email-recovery] start'); - $output->writeln(' - disableAccounts=' . ((bool)$disableAccounts ? 'true' : 'false')); - $output->writeln(' - deleteAccounts=' . ((bool)$deleteAccounts ? 'true' : 'false')); - $output->writeln(' - dryRun=' . ($this->dryRun ? 'true' : 'false')); - $output->writeln(' - testMode=' . ($this->testMode ? 'true' : 'false')); - - if ($this->dryRun) { - $output->writeln('Running in DRY-RUN mode - no actual actions will be taken'); - } + protected function execute(InputInterface $input, OutputInterface $output): int { + $disableAccounts = $input->getOption('disable-accounts'); + $deleteAccounts = $input->getOption('delete-accounts'); + $this->dryRun = $input->getOption('dry-run'); + $this->testMode = $input->getOption('test-mode'); - if ($this->testMode) { - $output->writeln('Test mode enabled - processing only ' . $this->testModeUserLimit . ' users'); - } + if ($this->dryRun) { + $output->writeln('Running in DRY-RUN mode - no actual actions will be taken'); + } - try { - if (!$this->messageId) { - $output->writeln('Error: messageId not configured in recovery_warning_configs system configuration!'); - return Command::FAILURE; + if ($this->testMode) { + $output->writeln('Test mode enabled - processing only ' . $this->testModeUserLimit . ' users'); } - // Initialize arrays - $this->uids = []; - $this->disableUids = []; - $this->deleteUids = []; - - // Process users - $identifyStart = microtime(true); - $this->identifyUnverifiedUsers($output); - $output->writeln('[email-recovery] identifyUnverifiedUsers completed'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $identifyStart)); - $output->writeln(' - notifyCandidates=' . count($this->uids)); - $output->writeln(' - disableCandidates=' . count($this->disableUids)); - $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); - - $notifyStart = microtime(true); - $this->sendNotificationsAndEmails($output); - $output->writeln('[email-recovery] sendNotificationsAndEmails completed'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $notifyStart)); + try { + if (!$this->messageId) { + $output->writeln('Error: messageId not configured in recovery_warning_configs system configuration!'); + return Command::FAILURE; + } + + // Initialize arrays + $this->uids = []; + $this->disableUids = []; + $this->deleteUids = []; + + // Process users + $this->identifyUnverifiedUsers($output); + $this->sendNotificationsAndEmails($output); - if ($disableAccounts) { - $disableStart = microtime(true); - $this->disableUnverifiedUsers($output); - $output->writeln('[email-recovery] disableUnverifiedUsers completed'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $disableStart)); - $output->writeln(' - disableCandidates=' . count($this->disableUids)); - } + if ($disableAccounts) { + $this->disableUnverifiedUsers($output); + } - if ($deleteAccounts) { - $deleteStart = microtime(true); - $this->deleteExpiredDisabledUsers($output); - $output->writeln('[email-recovery] deleteExpiredDisabledUsers completed'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $deleteStart)); - $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); - } + if ($deleteAccounts) { + $this->deleteExpiredDisabledUsers($output); + } - $output->writeln('=== Command Summary ==='); - $output->writeln(' - Users for notifications: ' . count($this->uids)); - $output->writeln(' - Users for disable: ' . count($this->disableUids)); - $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); - - $overallDuration = microtime(true) - $overallStart; - $output->writeln('[email-recovery] completed'); - $output->writeln(' - overallDurationMs=' . $this->toMs($overallDuration)); - $output->writeln(' - notifyCandidates=' . count($this->uids)); - $output->writeln(' - disableCandidates=' . count($this->disableUids)); - $output->writeln(' - deleteCandidates=' . count($this->deleteUids)); - $output->writeln('Recovery warning notification command completed successfully.'); - return Command::SUCCESS; - } catch (\Throwable $e) { - $output->writeln('Error: ' . $e->getMessage() . ''); - $output->writeln('[email-recovery] failed: ' . $e->getMessage() . ''); - return Command::FAILURE; + $output->writeln('=== Command Summary ==='); + $output->writeln(' - Users for notifications: ' . count($this->uids)); + $output->writeln(' - Users for disable: ' . count($this->disableUids)); + $output->writeln(' - Users for deletion: ' . count($this->deleteUids)); + + $output->writeln('Recovery warning notification command completed successfully.'); + return Command::SUCCESS; + } catch (\Throwable $e) { + $output->writeln('Error: ' . $e->getMessage() . ''); + return Command::FAILURE; + } } -} -private function identifyUnverifiedUsers(OutputInterface $output): void { - $stageStart = microtime(true); - $users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', ''); - if (!is_array($users)) { - $output->writeln('Error: Expected array for recovery-email users, got ' . gettype($users) . ''); - return; - } + private function identifyUnverifiedUsers(OutputInterface $output): void { + $users = $this->config->getUsersForUserValue(Application::APP_ID, 'recovery-email', ''); + if (!is_array($users)) { + $output->writeln('Error: Expected array for recovery-email users, got ' . gettype($users) . ''); + return; + } - // Limit to user-limit for test mode - if ($this->testMode && count($users) > $this->testModeUserLimit) { - $users = array_slice($users, 0, $this->testModeUserLimit); - $output->writeln('Test mode: Limited to ' . $this->testModeUserLimit . ' users'); - } + // Limit to user-limit for test mode + if ($this->testMode && count($users) > $this->testModeUserLimit) { + $users = array_slice($users, 0, $this->testModeUserLimit); + $output->writeln('Test mode: Limited to ' . $this->testModeUserLimit . ' users'); + } - $processedCount = 0; - $skippedCount = 0; - $invalidCount = 0; - $errorCount = 0; + $processedCount = 0; + $skippedCount = 0; + $invalidCount = 0; + $errorCount = 0; - // Aggregated timings (seconds) - $sumGetUser = 0.0; - $sumGetRecoveryEmail = 0.0; - $sumHasActiveSubscription = 0.0; - $sumConfigOps = 0.0; + foreach ($users as $username) { + try { + $user = $this->userManager->get($username); + if (!$user) { + $invalidCount++; + continue; + } - foreach ($users as $username) { - try { - $userStart = microtime(true); - $t = microtime(true); - $user = $this->userManager->get($username); - $dtGetUser = microtime(true) - $t; - $sumGetUser += $dtGetUser; - if (!$user) { - $invalidCount++; - $output->writeln('[identify] user=' . $username . ' getUserMs=' . $this->toMs($dtGetUser) . ' invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; - } + if (!$this->isUserValid($user)) { + $invalidCount++; + continue; + } - $t = microtime(true); - $isValid = $this->isUserValid($user); - $dtIsValid = microtime(true) - $t; - if (!$isValid) { - $invalidCount++; - $output->writeln('[identify] user=' . $username . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; - } + $uid = $user->getUID(); + $emailAddress = $user->getEMailAddress(); - $uid = $user->getUID(); - $emailAddress = $user->getEMailAddress(); - - // Check if user has a VERIFIED recovery email - $t = microtime(true); - $verifiedRecoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); - $dtGetRecovery = microtime(true) - $t; - $sumGetRecoveryEmail += $dtGetRecovery; - if (!empty($verifiedRecoveryEmail)) { - $skippedCount++; - $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' skipped=verifiedRecoveryEmail totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; - } + // Check if user has a VERIFIED recovery email + $verifiedRecoveryEmail = $this->recoveryEmailService->getRecoveryEmail($username); + if (!empty($verifiedRecoveryEmail)) { + $skippedCount++; + continue; + } - // Check for active subscription - $t = microtime(true); - $hasSub = $this->recoveryEmailService->hasActiveSubscription($emailAddress); - $dtHasSub = microtime(true) - $t; - $sumHasActiveSubscription += $dtHasSub; - if ($hasSub) { - $skippedCount++; - $output->writeln('[identify] user=' . $uid . ' getUserMs=' . $this->toMs($dtGetUser) . ' isValidMs=' . $this->toMs($dtIsValid) . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) . ' hasSubMs=' . $this->toMs($dtHasSub) . ' skipped=hasSubscription totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; - } + // Check for active subscription + if ($this->recoveryEmailService->hasActiveSubscription($emailAddress)) { + $skippedCount++; + continue; + } - // Get or set first run date - $tCfg = microtime(true); - $firstRunDate = $this->config->getUserValue($uid, Application::APP_ID, 'first-run-date', null); - // Ensure firstRunDate is an integer timestamp - $firstRunDate = $firstRunDate ? (int)$firstRunDate : null; + // Get or set first run date + $firstRunDate = $this->config->getUserValue($uid, Application::APP_ID, 'first-run-date', null); + // Ensure firstRunDate is an integer timestamp + $firstRunDate = $firstRunDate ? (int)$firstRunDate : null; - if ($firstRunDate === null) { - $firstRunDate = time(); - $this->config->setUserValue($uid, Application::APP_ID, 'first-run-date', $firstRunDate); - } - $dtFirstRunOps = microtime(true) - $tCfg; - $sumConfigOps += $dtFirstRunOps; + if ($firstRunDate === null) { + $firstRunDate = time(); + $this->config->setUserValue($uid, Application::APP_ID, 'first-run-date', $firstRunDate); + } - // Check if disable date is already set, if not set it - $tCfg = microtime(true); - $existingDisableDate = $this->recoveryEmailService->getUnverifiedUserDisableAt($uid); + // Check if disable date is already set, if not set it + $existingDisableDate = $this->recoveryEmailService->getUnverifiedUserDisableAt($uid); - if (empty($existingDisableDate)) { - // Set the disable date using config variable - $disableDate = date('Y-m-d', $firstRunDate + ($this->disableUserAfterUnverifiedDays * 24 * 60 * 60)); - $this->recoveryEmailService->setUnverifiedUserDisableAt($uid, $disableDate); - } - $dtDisableOps = microtime(true) - $tCfg; - $sumConfigOps += $dtDisableOps; + if (empty($existingDisableDate)) { + // Set the disable date using config variable + $disableDate = date('Y-m-d', $firstRunDate + ($this->disableUserAfterUnverifiedDays * 24 * 60 * 60)); + $this->recoveryEmailService->setUnverifiedUserDisableAt($uid, $disableDate); + } - // Calculate age and process - $age = (int) ((time() - $firstRunDate) / (24 * 60 * 60)); + // Calculate age and process + $age = (int) ((time() - $firstRunDate) / (24 * 60 * 60)); - if (in_array($age, $this->reminderDaysSinceStart)) { - $this->uids[] = $uid; - } + if (in_array($age, $this->reminderDaysSinceStart)) { + $this->uids[] = $uid; + } + + $this->identifyForDisable($user, $age); + $this->identifyForDelete($user, $age); - $t = microtime(true); - $this->identifyForDisable($user, $age); - $this->identifyForDelete($user, $age); - $dtFlags = microtime(true) - $t; - - $output->writeln('[identify] user=' . $uid - . ' getUserMs=' . $this->toMs($dtGetUser) - . ' isValidMs=' . $this->toMs($dtIsValid) - . ' getRecoveryMs=' . $this->toMs($dtGetRecovery) - . ' hasSubMs=' . $this->toMs($dtHasSub) - . ' firstRunOpsMs=' . $this->toMs($dtFirstRunOps) - . ' disableOpsMs=' . $this->toMs($dtDisableOps) - . ' age=' . $age - . ' notify=' . (in_array($age, $this->reminderDaysSinceStart) ? '1' : '0') - . ' flagsMs=' . $this->toMs($dtFlags) - . ' totalMs=' . $this->toMs(microtime(true) - $userStart) - ); - - $processedCount++; - if ($processedCount % 1000 === 0) { - $elapsed = microtime(true) - $stageStart; - $output->writeln('[email-recovery] identify progress'); - $output->writeln(' - processed=' . $processedCount); - $output->writeln(' - elapsedMs=' . $this->toMs($elapsed)); - $output->writeln(' - rateUsersPerMin=' . (int)($processedCount / max($elapsed, 0.0001) * 60)); - $output->writeln(' - memoryMb=' . (int)(memory_get_usage(true) / 1024 / 1024)); + $processedCount++; + } catch (\Throwable $e) { + $errorCount++; + $output->writeln('Error processing user ' . $username . ': ' . $e->getMessage() . ''); + continue; } - } catch (\Throwable $e) { - $errorCount++; - $output->writeln('Error processing user ' . $username . ': ' . $e->getMessage() . ''); - $output->writeln('[email-recovery] Error processing user in identify for ' . $username . ': ' . $e->getMessage() . ''); - continue; } - } - $output->writeln('User processing summary:'); - $output->writeln(' - Total users: ' . count($users)); - $output->writeln(' - Processed: ' . $processedCount); - $output->writeln(' - Skipped: ' . $skippedCount); - $output->writeln(' - Invalid: ' . $invalidCount); - $output->writeln(' - Errors: ' . $errorCount); - $output->writeln(' - For notifications: ' . count($this->uids)); - $output->writeln(' - For disable: ' . count($this->disableUids)); - $output->writeln(' - For deletion: ' . count($this->deleteUids)); - $output->writeln('[email-recovery] identifyUnverifiedUsers stats'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $stageStart)); - $output->writeln(' - totalUsers=' . count($users)); - $output->writeln(' - processed=' . $processedCount); - $output->writeln(' - skipped=' . $skippedCount); - $output->writeln(' - invalid=' . $invalidCount); - $output->writeln(' - errors=' . $errorCount); - $output->writeln(' - forNotifications=' . count($this->uids)); - $output->writeln(' - forDisable=' . count($this->disableUids)); - $output->writeln(' - forDeletion=' . count($this->deleteUids)); - $output->writeln(' - avgGetUserMs=' . ($processedCount ? $this->toMs($sumGetUser / $processedCount) : 0)); - $output->writeln(' - avgGetRecoveryEmailMs=' . ($processedCount ? $this->toMs($sumGetRecoveryEmail / $processedCount) : 0)); - $output->writeln(' - avgHasActiveSubscriptionMs=' . ($processedCount ? $this->toMs($sumHasActiveSubscription / $processedCount) : 0)); - $output->writeln(' - avgConfigOpsMs=' . ($processedCount ? $this->toMs($sumConfigOps / $processedCount) : 0)); -} + $output->writeln('User processing summary:'); + $output->writeln(' - Total users: ' . count($users)); + $output->writeln(' - Processed: ' . $processedCount); + $output->writeln(' - Skipped: ' . $skippedCount); + $output->writeln(' - Invalid: ' . $invalidCount); + $output->writeln(' - Errors: ' . $errorCount); + $output->writeln(' - For notifications: ' . count($this->uids)); + $output->writeln(' - For disable: ' . count($this->disableUids)); + $output->writeln(' - For deletion: ' . count($this->deleteUids)); + } private function identifyForDisable($user, int $age): void { if ($age >= $this->disableUserAfterUnverifiedDays) { @@ -367,15 +266,10 @@ private function identifyUnverifiedUsers(OutputInterface $output): void { } $output->writeln('Sending notifications and emails to ' . count($this->uids) . ' users...'); - $output->writeln('[email-recovery] sendNotificationsAndEmails start'); - $output->writeln(' - users=' . count($this->uids)); - $stageStart = microtime(true); - $sumNotification = 0.0; - $sumEmail = 0.0; try { $notification = $this->prepareCloudNotification(); - $stats = $this->processUsersForNotificationsAndEmails($notification, $output, $sumNotification, $sumEmail); + $stats = $this->processUsersForNotificationsAndEmails($notification, $output); $output->writeln('Notification/Email summary:'); $output->writeln(' - Notifications sent: ' . $stats['notificationSentCount']); @@ -383,18 +277,8 @@ private function identifyUnverifiedUsers(OutputInterface $output): void { $output->writeln(' - Emails sent: ' . $stats['emailSentCount']); $output->writeln(' - Emails failed: ' . $stats['emailFailedCount']); $output->writeln(' - No email address: ' . $stats['noEmailCount']); - $output->writeln('[email-recovery] sendNotificationsAndEmails stats'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $stageStart)); - $output->writeln(' - notificationsSent=' . $stats['notificationSentCount']); - $output->writeln(' - notificationsFailed=' . $stats['notificationFailedCount']); - $output->writeln(' - emailsSent=' . $stats['emailSentCount']); - $output->writeln(' - emailsFailed=' . $stats['emailFailedCount']); - $output->writeln(' - noEmail=' . $stats['noEmailCount']); - $output->writeln(' - avgNotifyMs=' . (($stats['notificationSentCount'] + $stats['notificationFailedCount']) ? $this->toMs($sumNotification / max(1, ($stats['notificationSentCount'] + $stats['notificationFailedCount']))) : 0)); - $output->writeln(' - avgEmailMs=' . (($stats['emailSentCount'] + $stats['emailFailedCount']) ? $this->toMs($sumEmail / max(1, ($stats['emailSentCount'] + $stats['emailFailedCount']))) : 0)); } catch (\Throwable $e) { $output->writeln('Error in sendNotificationsAndEmails: ' . $e->getMessage() . ''); - $output->writeln('[email-recovery] Error in sendNotificationsAndEmails: ' . $e->getMessage() . ''); } } @@ -411,54 +295,40 @@ private function identifyUnverifiedUsers(OutputInterface $output): void { return $notification; } -private function processUsersForNotificationsAndEmails($notification, OutputInterface $output, float &$sumNotification, float &$sumEmail): array { - $stats = [ - 'notificationSentCount' => 0, - 'notificationFailedCount' => 0, - 'emailSentCount' => 0, - 'emailFailedCount' => 0, - 'noEmailCount' => 0 - ]; + private function processUsersForNotificationsAndEmails($notification, OutputInterface $output): array { + $stats = [ + 'notificationSentCount' => 0, + 'notificationFailedCount' => 0, + 'emailSentCount' => 0, + 'emailFailedCount' => 0, + 'noEmailCount' => 0 + ]; - foreach ($this->uids as $uid) { - try { - $userStart = microtime(true); - $user = $this->userManager->get($uid); - if (!$user) { + foreach ($this->uids as $uid) { + try { + $user = $this->userManager->get($uid); + if (!$user) { + $stats['notificationFailedCount']++; + $stats['emailFailedCount']++; + continue; + } + + $username = $user->getDisplayName(); + $emailAddress = $user->getEMailAddress(); + + // Send cloud notification + $this->sendNotificationToUserIfValid($user, $notification, $stats, $output); + + // Send email + $this->sendEmailToUserIfValid($user, $emailAddress, $stats, $output); + } catch (\Throwable $e) { $stats['notificationFailedCount']++; $stats['emailFailedCount']++; - $output->writeln('[notify] user=' . $uid . ' getUserMs=0 invalid=1 totalMs=' . $this->toMs(microtime(true) - $userStart)); - continue; } - - $username = $user->getDisplayName(); - $emailAddress = $user->getEMailAddress(); - - // Send cloud notification - $t = microtime(true); - $this->sendNotificationToUserIfValid($user, $notification, $stats, $output); - $dtNotify = microtime(true) - $t; - $sumNotification += $dtNotify; - - // Send email - $t = microtime(true); - $this->sendEmailToUserIfValid($user, $emailAddress, $stats, $output); - $dtEmail = microtime(true) - $t; - $sumEmail += $dtEmail; - - $output->writeln('[notify] user=' . $uid - . ' notifyMs=' . $this->toMs($dtNotify) - . ' emailMs=' . $this->toMs($dtEmail) - . ' totalMs=' . $this->toMs(microtime(true) - $userStart) - ); - } catch (\Throwable $e) { - $stats['notificationFailedCount']++; - $stats['emailFailedCount']++; } - } - return $stats; -} + return $stats; + } private function sendNotificationToUserIfValid($user, $notification, array &$stats, OutputInterface $output): void { $username = $user->getDisplayName(); @@ -580,7 +450,6 @@ private function processUsersForNotificationsAndEmails($notification, OutputInte private function disableUnverifiedUsers(OutputInterface $output): void { $disabledCount = 0; $failedCount = 0; - $start = microtime(true); foreach ($this->disableUids as $uid) { try { @@ -604,17 +473,11 @@ private function processUsersForNotificationsAndEmails($notification, OutputInte $failedCount++; } } - - $output->writeln('[email-recovery] disableUnverifiedUsers stats'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $start)); - $output->writeln(' - disabled=' . $disabledCount); - $output->writeln(' - failed=' . $failedCount); } private function deleteExpiredDisabledUsers(OutputInterface $output): void { $deletedCount = 0; $failedCount = 0; - $start = microtime(true); foreach ($this->deleteUids as $uid) { try { @@ -640,11 +503,6 @@ private function processUsersForNotificationsAndEmails($notification, OutputInte $failedCount++; } } - - $output->writeln('[email-recovery] deleteExpiredDisabledUsers stats'); - $output->writeln(' - durationMs=' . $this->toMs(microtime(true) - $start)); - $output->writeln(' - deleted=' . $deletedCount); - $output->writeln(' - failed=' . $failedCount); } private function isUserValid($user): bool { @@ -655,8 +513,4 @@ private function processUsersForNotificationsAndEmails($notification, OutputInte $emailAddress = $user->getEMailAddress(); return $emailAddress && $this->mailer->validateMailAddress($emailAddress); } - -private function toMs(float $seconds): int { - return (int) round($seconds * 1000); -} } -- GitLab From 5fd74172b1d12528fc74ee52ec6be22c205bbd52 Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 23:08:11 +0530 Subject: [PATCH 7/8] reverted command --- .gitlab-ci.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ddd0278..ebc28ac 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,21 +28,3 @@ include: - project: "e/infra/ecloud/nextcloud-apps/ci-templates" ref: main file: "nc-publish-app.yml" - - -deploy:staging: - extends: .deploy:nextcloud-app - rules: - - if: $CI_COMMIT_BRANCH == "main" - when: manual - - if: $CI_COMMIT_BRANCH == "murena-main" - when: manual - - if: $CI_COMMIT_BRANCH == "production" - when: manual - - if: $CI_COMMIT_BRANCH == "dev/temp-logger" - when: manual - - if: $CI_COMMIT_TAG - when: manual - environment: - name: staging/01 - url: $ENV_URL \ No newline at end of file -- GitLab From 7f614113ff76ae36326cd6f1c90136dc3008de30 Mon Sep 17 00:00:00 2001 From: theronakpatel Date: Wed, 22 Oct 2025 23:08:50 +0530 Subject: [PATCH 8/8] reverted command --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ebc28ac..9215688 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,3 +28,4 @@ include: - project: "e/infra/ecloud/nextcloud-apps/ci-templates" ref: main file: "nc-publish-app.yml" + -- GitLab