|
5 | 5 | /** |
6 | 6 | * Access the file system. |
7 | 7 | * |
| 8 | + * ## iOS security-scoped resources |
| 9 | + * |
| 10 | + * On iOS, the `fs` plugin automatically manages access to security-scoped resources when a file URL is accessed. |
| 11 | + * This is required for files outside the app's sandbox (e.g., from file picker). |
| 12 | + * |
| 13 | + * @example |
| 14 | + * ```typescript |
| 15 | + * import { open } from '@tauri-apps/plugin-fs'; |
| 16 | + * |
| 17 | + * const file = await open('file:///path/to/file.txt'); |
| 18 | + * await file.close(); |
| 19 | + * ``` |
| 20 | + * |
8 | 21 | * ## Security |
9 | 22 | * |
10 | 23 | * This module prevents path traversal, not allowing parent directory accessors to be used |
@@ -1353,6 +1366,79 @@ async function size(path: string | URL): Promise<number> { |
1353 | 1366 | }) |
1354 | 1367 | } |
1355 | 1368 |
|
| 1369 | +/** |
| 1370 | + * Starts accessing a security-scoped resource for the given file URL. |
| 1371 | + * This should be called when you're accessing a file that was opened |
| 1372 | + * using a security-scoped URL (e.g., from a file picker). |
| 1373 | + * |
| 1374 | + * Note that accessing security-scoped resources is automatically managed by the plugin on iOS, so you don't need to call this function |
| 1375 | + * unless you want to manage the scope manually. |
| 1376 | + * |
| 1377 | + * You must call {@linkcode stopAccessingSecurityScopedResource} when you're done accessing the resource. |
| 1378 | + * |
| 1379 | + * #### Platform-specific |
| 1380 | + * |
| 1381 | + * - **iOS:** Starts accessing the security-scoped resource. |
| 1382 | + * - **Other platforms:** does nothing. |
| 1383 | + * |
| 1384 | + * @example |
| 1385 | + * ```typescript |
| 1386 | + * import { startAccessingSecurityScopedResource } from '@tauri-apps/plugin-fs'; |
| 1387 | + * |
| 1388 | + * const filePath = 'file:///path/to/file.txt'; |
| 1389 | + * await startAccessingSecurityScopedResource(filePath); |
| 1390 | + * // ... use the resource ... |
| 1391 | + * ``` |
| 1392 | + * |
| 1393 | + * @since 2.5.0 |
| 1394 | + */ |
| 1395 | +async function startAccessingSecurityScopedResource( |
| 1396 | + path: string | URL |
| 1397 | +): Promise<void> { |
| 1398 | + if (path instanceof URL && path.protocol !== 'file:') { |
| 1399 | + throw new TypeError('Must be a file URL.') |
| 1400 | + } |
| 1401 | + |
| 1402 | + await invoke('plugin:fs|start_accessing_security_scoped_resource', { |
| 1403 | + path: path instanceof URL ? path.toString() : path |
| 1404 | + }) |
| 1405 | +} |
| 1406 | + |
| 1407 | +/** |
| 1408 | + * Stops accessing a security-scoped resource for the given file URL. |
| 1409 | + * This should be called when you're done accessing a file that was opened |
| 1410 | + * using a security-scoped URL (e.g., from a file picker) when using manual tracking via {@linkcode startAccessingSecurityScopedResource}. |
| 1411 | + * |
| 1412 | + * #### Platform-specific |
| 1413 | + * |
| 1414 | + * - **iOS:** Stops accessing the security-scoped resource. |
| 1415 | + * - **Other platforms:** does nothing. |
| 1416 | + * |
| 1417 | + * @example |
| 1418 | + * ```typescript |
| 1419 | + * import { stopAccessingSecurityScopedResource } from '@tauri-apps/plugin-fs'; |
| 1420 | + * |
| 1421 | + * const filePath = 'file:///path/to/file.txt'; |
| 1422 | + * await startAccessingSecurityScopedResource(filePath); |
| 1423 | + * // ... use the resource ... |
| 1424 | + * // when you're done with the resource: |
| 1425 | + * await stopAccessingSecurityScopedResource(filePath); |
| 1426 | + * ``` |
| 1427 | + * |
| 1428 | + * @since 2.5.0 |
| 1429 | + */ |
| 1430 | +async function stopAccessingSecurityScopedResource( |
| 1431 | + path: string | URL |
| 1432 | +): Promise<void> { |
| 1433 | + if (path instanceof URL && path.protocol !== 'file:') { |
| 1434 | + throw new TypeError('Must be a file URL.') |
| 1435 | + } |
| 1436 | + |
| 1437 | + await invoke('plugin:fs|stop_accessing_security_scoped_resource', { |
| 1438 | + path: path instanceof URL ? path.toString() : path |
| 1439 | + }) |
| 1440 | +} |
| 1441 | + |
1356 | 1442 | export type { |
1357 | 1443 | CreateOptions, |
1358 | 1444 | OpenOptions, |
@@ -1401,5 +1487,7 @@ export { |
1401 | 1487 | exists, |
1402 | 1488 | watch, |
1403 | 1489 | watchImmediate, |
1404 | | - size |
| 1490 | + size, |
| 1491 | + startAccessingSecurityScopedResource, |
| 1492 | + stopAccessingSecurityScopedResource |
1405 | 1493 | } |
0 commit comments