Skip to content

Commit b5a3817

Browse files
committed
suggested changes for review
1 parent 90c375e commit b5a3817

14 files changed

Lines changed: 232 additions & 94 deletions

File tree

dev-env/docker-compose-dev.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ services:
7272
-Ddataverse.files.s3.connection-pool-size=2048
7373
-Ddataverse.files.s3.custom-endpoint-region=us-east-1
7474
-Ddataverse.files.s3.custom-endpoint-url=https://s3.us-east-1.amazonaws.com
75-
# We publish the port on the host machine instead of just exposing it within the network, so that the browser can access the URLs of images generated by Dataverse (http://localhost:8080...).
76-
# This is necessary because the dev_nginx proxy is placed on top of the Dataverse service, making those URLs unreachable unless this port is exposed.
75+
# We publish the port on the host machine instead of just exposing it within the network, so that the browser can access the URLs of images generated by Dataverse (http://localhost:8080...).
76+
# This is necessary because the dev_nginx proxy is placed on top of the Dataverse service, making those URLs unreachable unless this port is exposed.
7777
# This workaround is only necessary and intended for the local dev environment and will not be used in the remote environment, where we use a production DNS.
7878
ports:
7979
- '8080:8080'
@@ -128,6 +128,8 @@ services:
128128
interval: 10s
129129
timeout: 5s
130130
retries: 10
131+
ports:
132+
- '5432:5432'
131133
expose:
132134
- '5432'
133135
networks:
@@ -214,7 +216,7 @@ services:
214216
- DATAVERSE_DB_PORT=5432
215217
- DATAVERSE_DB_USER=${DATAVERSE_DB_USER}
216218
- DATAVERSE_DB_PASSWORD=secret
217-
- DATAVERSE_BASE_URL=http://dataverse:8080
219+
- DATAVERSE_BASE_URL=http://localhost:8000
218220
networks:
219221
dataverse:
220222
aliases:

dev-env/nginx.conf

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ http {
99
# Default route for other URLs
1010
location / {
1111
proxy_pass http://dataverse:8080;
12+
proxy_set_header Host $http_host;
13+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
14+
proxy_set_header X-Forwarded-Proto $scheme;
15+
proxy_set_header X-Forwarded-Host $http_host;
16+
proxy_set_header X-Forwarded-Port $server_port;
1217
}
1318

1419
# Keycloak reverse proxy for /realms
@@ -23,31 +28,61 @@ http {
2328
# Specific route for /resources/images
2429
location /resources/images {
2530
proxy_pass http://dataverse:8080;
31+
proxy_set_header Host $http_host;
32+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33+
proxy_set_header X-Forwarded-Proto $scheme;
34+
proxy_set_header X-Forwarded-Host $http_host;
35+
proxy_set_header X-Forwarded-Port $server_port;
2636
}
2737

2838
# Specific route for /resources/css
2939
location /resources/css {
3040
proxy_pass http://dataverse:8080;
41+
proxy_set_header Host $http_host;
42+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
43+
proxy_set_header X-Forwarded-Proto $scheme;
44+
proxy_set_header X-Forwarded-Host $http_host;
45+
proxy_set_header X-Forwarded-Port $server_port;
3146
}
3247

3348
# Specific route for /resources/js
3449
location /resources/js {
3550
proxy_pass http://dataverse:8080;
51+
proxy_set_header Host $http_host;
52+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
53+
proxy_set_header X-Forwarded-Proto $scheme;
54+
proxy_set_header X-Forwarded-Host $http_host;
55+
proxy_set_header X-Forwarded-Port $server_port;
3656
}
3757

3858
# Specific route for /resources/dev
3959
location /resources/dev {
4060
proxy_pass http://dataverse:8080;
61+
proxy_set_header Host $http_host;
62+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
63+
proxy_set_header X-Forwarded-Proto $scheme;
64+
proxy_set_header X-Forwarded-Host $http_host;
65+
proxy_set_header X-Forwarded-Port $server_port;
4166
}
4267

4368
# Specific route for /resources/fontcustom
4469
location /resources/fontcustom {
4570
proxy_pass http://dataverse:8080;
71+
proxy_set_header Host $http_host;
72+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
73+
proxy_set_header X-Forwarded-Proto $scheme;
74+
proxy_set_header X-Forwarded-Host $http_host;
75+
proxy_set_header X-Forwarded-Port $server_port;
4676
}
4777

4878
# Specific route for /resources/iqbs
4979
location /resources/iqbs {
5080
proxy_pass http://dataverse:8080;
81+
proxy_set_header Host $http_host;
82+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
83+
proxy_set_header X-Forwarded-Proto $scheme;
84+
proxy_set_header X-Forwarded-Host $http_host;
85+
proxy_set_header X-Forwarded-Port $server_port;
5186
}
5287

5388
# General route for other /resources routes, handled by Keycloak

dev-env/shib-dev-env/docker-compose-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ services:
208208
- DATAVERSE_DB_PORT=5432
209209
- DATAVERSE_DB_USER=${DATAVERSE_DB_USER}
210210
- DATAVERSE_DB_PASSWORD=secret
211-
- DATAVERSE_BASE_URL=http://dataverse:8080
211+
- DATAVERSE_BASE_URL=https://localhost
212212
networks:
213213
dataverse:
214214
aliases:

dev-env/shib-dev-env/nginx/nginx.conf

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ http {
1212
# Default route for other URLs
1313
location / {
1414
proxy_pass http://dataverse:8080;
15+
proxy_set_header Host $http_host;
16+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
17+
proxy_set_header X-Forwarded-Proto $scheme;
18+
proxy_set_header X-Forwarded-Host $http_host;
19+
proxy_set_header X-Forwarded-Port $server_port;
1520
}
1621

1722
# Keycloak reverse proxy for /realms
@@ -26,31 +31,61 @@ http {
2631
# Specific route for /resources/images
2732
location /resources/images {
2833
proxy_pass http://dataverse:8080;
34+
proxy_set_header Host $http_host;
35+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
36+
proxy_set_header X-Forwarded-Proto $scheme;
37+
proxy_set_header X-Forwarded-Host $http_host;
38+
proxy_set_header X-Forwarded-Port $server_port;
2939
}
3040

3141
# Specific route for /resources/css
3242
location /resources/css {
3343
proxy_pass http://dataverse:8080;
44+
proxy_set_header Host $http_host;
45+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
46+
proxy_set_header X-Forwarded-Proto $scheme;
47+
proxy_set_header X-Forwarded-Host $http_host;
48+
proxy_set_header X-Forwarded-Port $server_port;
3449
}
3550

3651
# Specific route for /resources/js
3752
location /resources/js {
3853
proxy_pass http://dataverse:8080;
54+
proxy_set_header Host $http_host;
55+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
56+
proxy_set_header X-Forwarded-Proto $scheme;
57+
proxy_set_header X-Forwarded-Host $http_host;
58+
proxy_set_header X-Forwarded-Port $server_port;
3959
}
4060

4161
# Specific route for /resources/dev
4262
location /resources/dev {
4363
proxy_pass http://dataverse:8080;
64+
proxy_set_header Host $http_host;
65+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66+
proxy_set_header X-Forwarded-Proto $scheme;
67+
proxy_set_header X-Forwarded-Host $http_host;
68+
proxy_set_header X-Forwarded-Port $server_port;
4469
}
4570

4671
# Specific route for /resources/fontcustom
4772
location /resources/fontcustom {
4873
proxy_pass http://dataverse:8080;
74+
proxy_set_header Host $http_host;
75+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
76+
proxy_set_header X-Forwarded-Proto $scheme;
77+
proxy_set_header X-Forwarded-Host $http_host;
78+
proxy_set_header X-Forwarded-Port $server_port;
4979
}
5080

5181
# Specific route for /resources/iqbs
5282
location /resources/iqbs {
5383
proxy_pass http://dataverse:8080;
84+
proxy_set_header Host $http_host;
85+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
86+
proxy_set_header X-Forwarded-Proto $scheme;
87+
proxy_set_header X-Forwarded-Host $http_host;
88+
proxy_set_header X-Forwarded-Port $server_port;
5489
}
5590

5691
# General route for other /resources routes, handled by Keycloak

src/sections/dataset/dataset-action-buttons/DatasetActionButtons.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function DatasetActionButtons({
3434
return (
3535
<ButtonGroup aria-label={t('datasetActionButtons.title')} vertical className={styles.group}>
3636
<AccessDatasetMenu
37+
datasetNumericId={dataset.id}
3738
version={dataset.version}
3839
permissions={dataset.permissions}
3940
hasOneTabularFileAtLeast={dataset.hasOneTabularFileAtLeast}

src/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.tsx

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState } from 'react'
22
import { DropdownButton, DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system'
33
import { Download as DownloadIcon } from 'react-bootstrap-icons'
44
import { useTranslation } from 'react-i18next'
5+
import { toast } from 'react-toastify'
56
import {
67
CustomTerms,
78
DatasetDownloadUrls,
@@ -13,10 +14,12 @@ import {
1314
import { FileDownloadSize, FileDownloadMode } from '../../../../files/domain/models/FileMetadata'
1415
import { DatasetExploreOptions } from '../DatasetToolsOptions'
1516
import { DownloadWithGuestbookModal } from '@/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/DownloadWithGuestbookModal'
17+
import { triggerAuthenticatedDownload } from '@/shared/helpers/AuthenticatedDownloadHelper'
1618

1719
// TODO: add compute feature
1820

1921
interface AccessDatasetMenuProps {
22+
datasetNumericId?: number | string
2023
version: DatasetVersion
2124
permissions: DatasetPermissions
2225
hasOneTabularFileAtLeast: boolean
@@ -30,6 +33,7 @@ interface AccessDatasetMenuProps {
3033
}
3134

3235
export function AccessDatasetMenu({
36+
datasetNumericId,
3337
version,
3438
permissions,
3539
hasOneTabularFileAtLeast,
@@ -90,7 +94,7 @@ export function AccessDatasetMenu({
9094
<DownloadWithGuestbookModal
9195
show={showDownloadWithGuestbookModal}
9296
handleClose={() => setShowDownloadWithGuestbookModal(false)}
93-
datasetId={persistentId}
97+
datasetId={datasetNumericId ?? persistentId}
9498
datasetPersistentId={persistentId}
9599
guestbookId={guestbookId}
96100
datasetLicense={license}
@@ -117,6 +121,27 @@ const DatasetDownloadOptions = ({
117121
onDownloadWithGuestbook
118122
}: DatasetDownloadOptionsProps) => {
119123
const { t } = useTranslation('dataset')
124+
const { t: tFiles } = useTranslation('files')
125+
126+
const handleDirectDownload = (
127+
event: React.MouseEvent<HTMLElement>,
128+
url: string | undefined
129+
): void => {
130+
if (hasGuestbook) {
131+
onDownloadWithGuestbook(event)
132+
return
133+
}
134+
135+
if (!url) {
136+
return
137+
}
138+
139+
event.preventDefault()
140+
void triggerAuthenticatedDownload(url).catch(() => {
141+
toast.error(tFiles('actions.optionsMenu.guestbookCollectModal.downloadError'))
142+
})
143+
}
144+
120145
function getFormattedFileSize(mode: FileDownloadMode): string {
121146
const foundSize = fileDownloadSizes.find((size) => size.mode === mode)
122147
return foundSize ? foundSize.toString() : ''
@@ -125,22 +150,22 @@ const DatasetDownloadOptions = ({
125150
return hasOneTabularFileAtLeast ? (
126151
<>
127152
<DropdownButtonItem
128-
href={hasGuestbook ? undefined : downloadUrls[FileDownloadMode.ORIGINAL]}
129-
onClick={hasGuestbook ? onDownloadWithGuestbook : undefined}>
153+
href={undefined}
154+
onClick={(event) => handleDirectDownload(event, downloadUrls[FileDownloadMode.ORIGINAL])}>
130155
{t('datasetActionButtons.accessDataset.downloadOptions.originalZip')} (
131156
{getFormattedFileSize(FileDownloadMode.ORIGINAL)})
132157
</DropdownButtonItem>
133158
<DropdownButtonItem
134-
href={hasGuestbook ? undefined : downloadUrls[FileDownloadMode.ARCHIVAL]}
135-
onClick={hasGuestbook ? onDownloadWithGuestbook : undefined}>
159+
href={undefined}
160+
onClick={(event) => handleDirectDownload(event, downloadUrls[FileDownloadMode.ARCHIVAL])}>
136161
{t('datasetActionButtons.accessDataset.downloadOptions.archivalZip')} (
137162
{getFormattedFileSize(FileDownloadMode.ARCHIVAL)})
138163
</DropdownButtonItem>
139164
</>
140165
) : (
141166
<DropdownButtonItem
142-
href={hasGuestbook ? undefined : downloadUrls[FileDownloadMode.ORIGINAL]}
143-
onClick={hasGuestbook ? onDownloadWithGuestbook : undefined}>
167+
href={undefined}
168+
onClick={(event) => handleDirectDownload(event, downloadUrls[FileDownloadMode.ORIGINAL])}>
144169
{t('datasetActionButtons.accessDataset.downloadOptions.zip')} (
145170
{getFormattedFileSize(FileDownloadMode.ORIGINAL)})
146171
</DropdownButtonItem>

src/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.tsx

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import { Download } from 'react-bootstrap-icons'
22
import { useTranslation } from 'react-i18next'
33
import { Button, DropdownButton, DropdownButtonItem } from '@iqss/dataverse-design-system'
44
import { MouseEvent, useState } from 'react'
5+
import { toast } from 'react-toastify'
56
import { FileDownloadMode } from '../../../../../../files/domain/models/FileMetadata'
67
import { useDataset } from '../../../../DatasetContext'
78
import { FileSelection } from '../../row-selection/useFileSelection'
89
import { NoSelectedFilesModal } from '../no-selected-files-modal/NoSelectedFilesModal'
910
import { useMultipleFileDownload } from '../../../../../file/multiple-file-download/MultipleFileDownloadContext'
1011
import { FilePreview } from '../../../../../../files/domain/models/FilePreview'
1112
import { useMediaQuery } from '../../../../../../shared/hooks/useMediaQuery'
12-
import { DatasetPublishingStatus } from '@/dataset/domain/models/Dataset'
1313
import { DownloadWithGuestbookModal } from '../file-actions-cell/file-action-buttons/file-options-menu/DownloadWithGuestbookModal'
14+
import { triggerAuthenticatedDownload } from '@/shared/helpers/AuthenticatedDownloadHelper'
1415
import styles from './DownloadFilesButton.module.scss'
1516

1617
interface DownloadFilesButtonProps {
@@ -36,7 +37,7 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
3637
: getFileIdsFromSelection(fileSelection)
3738
const hasGuestbook = dataset?.guestbookId !== undefined
3839

39-
const onClick = (event: MouseEvent<HTMLElement>) => {
40+
const onClick = (event: MouseEvent<HTMLElement>, downloadMode?: FileDownloadMode) => {
4041
if (fileSelectionCount === SELECTED_FILES_EMPTY) {
4142
event.preventDefault()
4243
setShowNoFilesSelectedModal(true)
@@ -46,6 +47,14 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
4647
if (hasGuestbook) {
4748
event.preventDefault()
4849
setShowDownloadWithGuestbookModal(true)
50+
return
51+
}
52+
53+
if (downloadMode) {
54+
event.preventDefault()
55+
void triggerAuthenticatedDownload(getDownloadUrl(downloadMode)).catch(() => {
56+
toast.error(t('actions.optionsMenu.guestbookCollectModal.downloadError'))
57+
})
4958
}
5059
}
5160

@@ -69,11 +78,6 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
6978
return <></>
7079
}
7180

72-
// TODO: remove this when access datafile supports bearer tokens
73-
if (dataset.version.publishingStatus === DatasetPublishingStatus.DRAFT) {
74-
return <></>
75-
}
76-
7781
const dropdownButtonTitle = isBelow768px
7882
? ''
7983
: /* istanbul ignore next */ t('actions.downloadFiles.title')
@@ -108,13 +112,13 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
108112
variant="secondary"
109113
withSpacing>
110114
<DropdownButtonItem
111-
onClick={onClick}
112-
href={hasGuestbook ? undefined : getDownloadUrl(FileDownloadMode.ORIGINAL)}>
115+
onClick={(event) => onClick(event, FileDownloadMode.ORIGINAL)}
116+
href={undefined}>
113117
{t('actions.downloadFiles.options.original')}
114118
</DropdownButtonItem>
115119
<DropdownButtonItem
116-
onClick={onClick}
117-
href={hasGuestbook ? undefined : getDownloadUrl(FileDownloadMode.ARCHIVAL)}>
120+
onClick={(event) => onClick(event, FileDownloadMode.ARCHIVAL)}
121+
href={undefined}>
118122
{t('actions.downloadFiles.options.archival')}
119123
</DropdownButtonItem>
120124
</DropdownButton>
@@ -133,21 +137,19 @@ export function DownloadFilesButton({ files, fileSelection }: DownloadFilesButto
133137
icon={<Download className={styles.icon} />}
134138
aria-label={t('actions.downloadFiles.title')}
135139
withSpacing
136-
onClick={onClick}>
140+
onClick={(event) => onClick(event, FileDownloadMode.ORIGINAL)}>
137141
{dropdownButtonTitle}
138142
</Button>
139143
) : (
140-
<a href={getDownloadUrl(FileDownloadMode.ORIGINAL)}>
141-
<Button
142-
id="download-files"
143-
variant="secondary"
144-
icon={<Download className={styles.icon} />}
145-
aria-label={t('actions.downloadFiles.title')}
146-
withSpacing
147-
onClick={onClick}>
148-
{dropdownButtonTitle}
149-
</Button>
150-
</a>
144+
<Button
145+
id="download-files"
146+
variant="secondary"
147+
icon={<Download className={styles.icon} />}
148+
aria-label={t('actions.downloadFiles.title')}
149+
withSpacing
150+
onClick={(event) => onClick(event, FileDownloadMode.ORIGINAL)}>
151+
{dropdownButtonTitle}
152+
</Button>
151153
)}
152154

153155
{downloadFeedbackModals}

0 commit comments

Comments
 (0)