* Retrieves information for a shared file from a shared folder link. */
(string $token, string $path, ?string $providedPass = null)
| 2847 | * Retrieves information for a shared file from a shared folder link. |
| 2848 | */ |
| 2849 | public static function getSharedFileInfo(string $token, string $path, ?string $providedPass = null): array |
| 2850 | { |
| 2851 | $record = self::findShareFolderRecord($token); |
| 2852 | if (!$record) { |
| 2853 | return ["error" => "Share link not found."]; |
| 2854 | } |
| 2855 | |
| 2856 | if (time() > ($record['expires'] ?? 0)) { |
| 2857 | return ["error" => "This share link has expired."]; |
| 2858 | } |
| 2859 | |
| 2860 | if (!empty($record['password']) && ($providedPass === null || $providedPass === '')) { |
| 2861 | return ["needs_password" => true]; |
| 2862 | } |
| 2863 | if (!empty($record['password']) && !password_verify((string)$providedPass, $record['password'])) { |
| 2864 | return ["error" => "Invalid password."]; |
| 2865 | } |
| 2866 | |
| 2867 | if (self::isShareDropMode($record)) { |
| 2868 | return ["error" => "Downloads are disabled for this upload-only share."]; |
| 2869 | } |
| 2870 | |
| 2871 | // Encrypted folders/descendants: shared access is blocked (v1). |
| 2872 | $folderKey = trim((string)($record['folder'] ?? ''), "/\\ "); |
| 2873 | $folderKey = ($folderKey === '' ? 'root' : $folderKey); |
| 2874 | try { |
| 2875 | if (FolderCrypto::isEncryptedOrAncestor($folderKey)) { |
| 2876 | return ["error" => "This shared folder is not accessible (encrypted folders cannot be shared)."]; |
| 2877 | } |
| 2878 | } catch (\Throwable $e) { |
| 2879 | /* ignore */ |
| 2880 | } |
| 2881 | |
| 2882 | $allowSubfolders = !empty($record['allowSubfolders']); |
| 2883 | [$subPath, $file, $pathErr] = self::splitShareFilePath($path); |
| 2884 | if ($pathErr) { |
| 2885 | return ["error" => $pathErr]; |
| 2886 | } |
| 2887 | if ($subPath !== '' && !$allowSubfolders) { |
| 2888 | return ["error" => "Subfolder access is not enabled for this share."]; |
| 2889 | } |
| 2890 | $combinedKey = self::buildSharedFolderKey($folderKey, $subPath); |
| 2891 | if ($combinedKey !== $folderKey) { |
| 2892 | try { |
| 2893 | if (FolderCrypto::isEncryptedOrAncestor($combinedKey)) { |
| 2894 | return ["error" => "This shared folder is not accessible (encrypted folders cannot be shared)."]; |
| 2895 | } |
| 2896 | } catch (\Throwable $e) { |
| 2897 | /* ignore */ |
| 2898 | } |
| 2899 | } |
| 2900 | |
| 2901 | $storage = self::storage(); |
| 2902 | [$shareRootPath,, $rootErr] = self::resolveFolderPath($folderKey, false); |
| 2903 | if ($rootErr) { |
| 2904 | return ["error" => "Shared folder not found."]; |
| 2905 | } |
| 2906 | $rootStat = $storage->stat($shareRootPath); |
no test coverage detected