diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
index 77e9ac4fbf2d91e2dc38ccf50a5d2c2ebeba0412..f1227f376debabac67424083d2854513be741769 100644
--- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
+++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/files/FileManager.kt
@@ -60,9 +60,14 @@ class FileManager @Inject constructor(
         randomIdManager.assertIsRandomId(folderId)
         authManager.assertCanDownloadFromFolder(principal, folderId)
 
-        // TODO implement
-
-        call.respond(HttpStatusCode.OK, "get: Not yet implemented. folderId: $folderId")
+        val fileListResponse = withContext(Dispatchers.IO) {
+            val list = ArrayList<FileResponse>()
+            fileProvider.getFolder(folderId).listFiles()?.forEach { file ->
+                list.add(FileResponse(file.name, file.lastModified()))
+            }
+            FileListResponse(list)
+        }
+        call.respond(HttpStatusCode.OK, fileListResponse)
     }
 
     /**
@@ -122,3 +127,6 @@ class FileManager @Inject constructor(
     }
 
 }
+
+data class FileListResponse(val files: ArrayList<FileResponse>)
+data class FileResponse(val name: String, val time: Long)
diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/files/FileManagerIntegrationTest.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/files/FileManagerIntegrationTest.kt
index 1b72883219e6b6a88c9808c0444976e8344ad8a2..25d5a739c50c47da69e8aac4731b8c561d9d4648 100644
--- a/mailbox-core/src/test/java/org/briarproject/mailbox/core/files/FileManagerIntegrationTest.kt
+++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/files/FileManagerIntegrationTest.kt
@@ -1,5 +1,7 @@
 package org.briarproject.mailbox.core.files
 
+import io.ktor.client.call.receive
+import io.ktor.client.request.get
 import io.ktor.client.request.post
 import io.ktor.client.statement.HttpResponse
 import io.ktor.client.statement.readText
@@ -53,14 +55,64 @@ class FileManagerIntegrationTest : IntegrationTest() {
     }
 
     @Test
-    fun `post new file creates new file`(): Unit = runBlocking {
+    fun `post new file, list, download and delete it`(): Unit = runBlocking {
+        // owner uploads the file
         val response: HttpResponse = httpClient.post("$baseUrl/files/${contact1.inboxId}") {
             authenticateWithToken(ownerToken)
             body = bytes
         }
         assertEquals(HttpStatusCode.OK.value, response.status.value)
 
+        // contact can list the file
+        val listResponse: HttpResponse = httpClient.get("$baseUrl/files/${contact1.inboxId}") {
+            authenticateWithToken(contact1.token)
+        }
+        assertEquals(HttpStatusCode.OK.value, listResponse.status.value)
+        val fileList: FileListResponse = listResponse.receive()
+        assertEquals(1, fileList.files.size)
+
         // TODO fetch the file later to see that it was uploaded correctly
+        val fileId = fileList.files[0].name
+
+        // TODO delete the file to clean up again
+    }
+
+    @Test
+    fun `list files rejects wrong token`(): Unit = runBlocking {
+        val response: HttpResponse = httpClient.get("$baseUrl/files/${getNewRandomId()}") {
+            authenticateWithToken(token)
+            body = bytes
+        }
+        assertEquals(HttpStatusCode.Unauthorized.value, response.status.value)
+    }
+
+    @Test
+    fun `list files rejects unauthorized folder ID`(): Unit = runBlocking {
+        val response: HttpResponse = httpClient.get("$baseUrl/files/${contact1.inboxId}") {
+            authenticateWithToken(ownerToken)
+            body = bytes
+        }
+        assertEquals(HttpStatusCode.Unauthorized.value, response.status.value)
+    }
+
+    @Test
+    fun `list files rejects invalid folder ID`(): Unit = runBlocking {
+        val response: HttpResponse = httpClient.get("$baseUrl/files/foo") {
+            authenticateWithToken(ownerToken)
+            body = bytes
+        }
+        assertEquals(HttpStatusCode.BadRequest.value, response.status.value)
+        assertEquals("Malformed ID: foo", response.readText())
+    }
+
+    @Test
+    fun `list files gives empty response for empty folder`(): Unit = runBlocking {
+        val response: HttpResponse = httpClient.get("$baseUrl/files/${contact1.outboxId}") {
+            authenticateWithToken(ownerToken)
+            body = bytes
+        }
+        assertEquals(HttpStatusCode.OK.value, response.status.value)
+        assertEquals("""{"files":[]}""", response.readText())
     }
 
 }