Skip to content

Commit a448992

Browse files
committed
feat: use query param for download tokens
1 parent d209413 commit a448992

5 files changed

Lines changed: 16 additions & 12 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,13 @@ Response: { "token": "<jwt_token>" }
421421
**Download file (forces download):**
422422

423423
```
424-
GET /attachment/download/file/{token}
424+
GET /attachment/download/file?token={token}
425425
```
426426

427427
**Stream file inline (for video/PDF preview):**
428428

429429
```
430-
GET /attachment/download/stream/{token}
430+
GET /attachment/download/stream?token={token}
431431
```
432432

433433
**Get ZIP token for multiple files:**

config/routes.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
'Trois/Attachment',
3131
['path' => '/attachment'],
3232
function (RouteBuilder $builder): void {
33-
// Download routes - must be before setExtensions to avoid JWT token parsing issues
34-
$builder->connect('/download/file/{token}', ['controller' => 'Download', 'action' => 'file'], ['pass' => ['token']]);
35-
$builder->connect('/download/stream/{token}', ['controller' => 'Download', 'action' => 'stream'], ['pass' => ['token']]);
33+
// Download routes - token passed as query param to avoid JWT parsing issues
34+
$builder->connect('/download/file', ['controller' => 'Download', 'action' => 'file']);
35+
$builder->connect('/download/stream', ['controller' => 'Download', 'action' => 'stream']);
3636
$builder->connect('/download/get-file-token', ['controller' => 'Download', 'action' => 'getFileToken']);
3737
$builder->connect('/download/get-zip-token', ['controller' => 'Download', 'action' => 'getZipToken']);
3838
$builder->connect('/download/files', ['controller' => 'Download', 'action' => 'files']);

resources/assets/components/Attachment.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ export default
237237
client.post(this.settings.url + 'attachment/download/get-file-token', { file: attachment.id })
238238
.then((response) => {
239239
const token = response.data.token
240-
return client.get(this.settings.url + 'attachment/download/file/' + token, {responseType: 'arraybuffer'})
240+
return client.get(this.settings.url + 'attachment/download/file?token=' + token, {responseType: 'arraybuffer'})
241241
})
242242
.then(async (response) => {
243243
await this.forceFileDownload(response, attachment)

resources/assets/components/Preview.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ export default {
129129
// Check if profile uses secure download
130130
if (profile && profile.secureDownload) {
131131
// Token-based secure download
132-
client.post(this.settings.url + 'attachment/download/get-file-token.json', { file: attachment.id })
132+
client.post(this.settings.url + 'attachment/download/get-file-token', { file: attachment.id })
133133
.then((response) => {
134134
const token = response.data.token
135-
return client.get(this.settings.url + 'attachment/download/file/' + token, {responseType: 'arraybuffer'})
135+
return client.get(this.settings.url + 'attachment/download/file?token=' + token, {responseType: 'arraybuffer'})
136136
})
137137
.then((response) => {
138138
this.forceFileDownload(response, attachment)
@@ -160,7 +160,7 @@ export default {
160160
161161
// Fetch token for video/PDF preview
162162
if (attachment.type === 'video' || attachment.subtype === 'pdf') {
163-
client.post(this.settings.url + 'attachment/download/get-file-token.json', { file: attachment.id })
163+
client.post(this.settings.url + 'attachment/download/get-file-token', { file: attachment.id })
164164
.then((response) => {
165165
this.$set(this.previewTokens, attachment.id, response.data.token)
166166
})
@@ -171,7 +171,7 @@ export default {
171171
const profile = this.$store.get(this.aid + '/settings.profiles.' + attachment.profile)
172172
173173
if (profile && profile.secureDownload && this.previewTokens[attachment.id]) {
174-
return this.settings.url + 'attachment/download/stream/' + this.previewTokens[attachment.id]
174+
return this.settings.url + 'attachment/download/stream?token=' + this.previewTokens[attachment.id]
175175
}
176176
return attachment.url
177177
},

src/Controller/DownloadController.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ public function getFileToken()
4444
$this->viewBuilder()->setOption('serialize', ['token']);
4545
}
4646
// (new Token)->encode(['file' => $attachment->id])
47-
public function file($token)
47+
public function file()
4848
{
49+
$token = $this->getRequest()->getQuery('token');
50+
if (empty($token)) throw new BadRequestException('Token required');
4951
// get Attachment
5052
$attachment = $this->fetchTable('Trois/Attachment.Attachments')->find()
5153
->where(['id' => (new Token)->decode($token)->file])
@@ -61,8 +63,10 @@ public function file($token)
6163
* Stream file inline for preview (videos, PDFs)
6264
* Unlike file() which forces download, this renders inline in browser
6365
*/
64-
public function stream($token)
66+
public function stream()
6567
{
68+
$token = $this->getRequest()->getQuery('token');
69+
if (empty($token)) throw new BadRequestException('Token required');
6670
// get Attachment
6771
$attachment = $this->fetchTable('Trois/Attachment.Attachments')->find()
6872
->where(['id' => (new Token)->decode($token)->file])

0 commit comments

Comments
 (0)