Skip to content

Commit 6762a86

Browse files
authored
Fix WireGuard config and LDAP saving bugs (#2827)
* fix displaying configs for mfa locations, fix downloading configs * send location mfa mode * dont show button if no locations viable * fix * fix
1 parent 16d1643 commit 6762a86

9 files changed

Lines changed: 51 additions & 17 deletions

File tree

.sqlx/query-27458fd8de7671429d382e5e27b71dd8c19286c201303bf2eb1dd0c3c004cad0.json renamed to .sqlx/query-e2d5bb28064afd6169f6078dc06edc7a62ac4c807dd36a025611d71cc8d11919.json

Lines changed: 19 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/defguard_common/src/db/models/device.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ pub struct UserDeviceNetworkInfo {
232232
pub last_connected_ip: Option<String>,
233233
pub last_connected_at: Option<NaiveDateTime>,
234234
pub is_active: bool,
235+
pub location_mfa_mode: LocationMfaMode,
235236
}
236237

237238
impl UserDevice {
@@ -242,7 +243,8 @@ impl UserDevice {
242243
wnd.wireguard_ips \"device_wireguard_ips: Vec<IpAddr>\", \
243244
latest_successful_stats.endpoint \"device_endpoint?\", \
244245
latest_successful_session.connected_at \"last_connected_at?\", \
245-
latest_successful_session.state \"state?: VpnClientSessionState\" \
246+
latest_successful_session.state \"state?: VpnClientSessionState\", \
247+
n.location_mfa_mode \"location_mfa_mode: LocationMfaMode\" \
246248
FROM wireguard_network_device wnd \
247249
JOIN wireguard_network n ON n.id = wnd.wireguard_network_id \
248250
LEFT JOIN LATERAL ( \
@@ -297,6 +299,7 @@ impl UserDevice {
297299
last_connected_ip: device_ip,
298300
last_connected_at: r.last_connected_at,
299301
is_active,
302+
location_mfa_mode: r.location_mfa_mode,
300303
}
301304
})
302305
.collect::<Vec<_>>();

crates/defguard_core/src/handlers/network_devices.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use defguard_common::{
1515
models::{
1616
Device, DeviceConfig, DeviceType, Settings, User, WireguardNetwork,
1717
device::{DeviceInfo, WireguardNetworkDevice},
18-
wireguard::NetworkAddressError,
18+
wireguard::{LocationMfaMode, NetworkAddressError},
1919
},
2020
},
2121
utils::{SplitIp, split_ip},
@@ -120,6 +120,7 @@ pub(crate) struct DeviceWireGuardConfig {
120120
pub(crate) network_id: Id,
121121
pub(crate) network_name: String,
122122
pub(crate) config: String,
123+
pub(crate) location_mfa_mode: LocationMfaMode,
123124
}
124125

125126
/// For a given device, retrieve all WireGuard configuations for all networks.
@@ -162,6 +163,7 @@ pub(crate) async fn network_device_configs(
162163
network_id: network.id,
163164
network_name: network.name,
164165
config,
166+
location_mfa_mode: network.location_mfa_mode.clone(),
165167
};
166168
result.push(device_config);
167169
}

crates/defguard_core/src/handlers/wireguard.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ pub(crate) async fn user_device_configs(
13951395
network_id: location.id,
13961396
network_name: location.name,
13971397
config,
1398+
location_mfa_mode: location.location_mfa_mode.clone(),
13981399
});
13991400
}
14001401

web/src/pages/UsersOverviewPage/UsersTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { orderBy } from 'lodash-es';
1616
import { useCallback, useMemo, useState } from 'react';
1717
import { m } from '../../paraglide/messages';
1818
import api from '../../shared/api/api';
19-
import type { Device, User } from '../../shared/api/types';
19+
import { type Device, LocationMfaMode, type User } from '../../shared/api/types';
2020
import { useSelectionModal } from '../../shared/components/modals/SelectionModal/useSelectionModal';
2121
import type { SelectionOption } from '../../shared/components/SelectionSection/type';
2222
import { TableValuesListCell } from '../../shared/components/TableValuesListCell/TableValuesListCell';
@@ -558,7 +558,7 @@ export const UsersTable = () => {
558558
},
559559
];
560560

561-
if (device.networks.length > 0) {
561+
if (device.networks.some((n) => n.location_mfa_mode === LocationMfaMode.Disabled)) {
562562
items.push({
563563
text: m.profile_devices_menu_show_config(),
564564
onClick: () => {

web/src/pages/settings/SettingsLdapPage/SettingsLdapPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ const PageForm = () => {
197197
onSubmit: formSchema,
198198
onChange: formSchema,
199199
},
200-
onSubmit: async ({ value }) => {
200+
onSubmit: async ({ value, formApi }) => {
201201
const licenseCheckRes = canUseBusinessFeature(licenseInfo);
202202
if (!licenseCheckRes.result) {
203203
openModal(ModalName.UpgradeBusiness);
@@ -219,6 +219,7 @@ const PageForm = () => {
219219
.filter(Boolean)
220220
: [],
221221
});
222+
formApi.reset(value);
222223
},
223224
});
224225

web/src/pages/user-profile/UserProfilePage/tabs/ProfileDevicesTab/components/ProfileDevicesTable/ProfileDevicesTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import orderBy from 'lodash-es/orderBy';
1313
import { useCallback, useMemo } from 'react';
1414
import { m } from '../../../../../../../paraglide/messages';
1515
import api from '../../../../../../../shared/api/api';
16-
import type { UserDevice } from '../../../../../../../shared/api/types';
16+
import { LocationMfaMode, type UserDevice } from '../../../../../../../shared/api/types';
1717
import { useAddUserDeviceModal } from '../../../../../../../shared/components/modals/AddUserDeviceModal/store/useAddUserDeviceModal';
1818
import { Badge } from '../../../../../../../shared/defguard-ui/components/Badge/Badge';
1919
import { Button } from '../../../../../../../shared/defguard-ui/components/Button/Button';
@@ -158,7 +158,7 @@ const DevicesTable = ({ rowData }: { rowData: RowData[] }) => {
158158
},
159159
});
160160
}
161-
if (row.networks.length > 0) {
161+
if (row.networks.some((n) => n.location_mfa_mode === LocationMfaMode.Disabled)) {
162162
items.push({
163163
text: m.profile_devices_menu_show_config(),
164164
onClick: () => {

web/src/shared/api/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ export interface DeviceNetworkInfo {
330330
network_name: string;
331331
last_connected_at?: string;
332332
last_connected_ip?: string;
333+
location_mfa_mode: LocationMfaModeValue;
333334
}
334335

335336
export interface Device {
@@ -540,6 +541,7 @@ export interface AddDeviceResponseConfig {
540541
network_id: number;
541542
network_name: string;
542543
config: string;
544+
location_mfa_mode: LocationMfaModeValue;
543545
}
544546

545547
export interface AddDeviceResponse {

web/src/shared/components/ModalDeviceConfigSection/ModalDeviceConfigSection.tsx

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { AddDeviceResponse, AddDeviceResponseConfig } from '../../api/types';
2+
import { LocationMfaMode } from '../../api/types';
23
import './style.scss';
34
import { ZipArchive } from '@shortercode/webzip';
45
import { useCallback, useMemo, useState } from 'react';
@@ -23,8 +24,11 @@ const configToOption = (
2324
value: item,
2425
});
2526

27+
const configToLocationName = (item: AddDeviceResponseConfig): string =>
28+
item.network_name.toLowerCase().replaceAll(' ', '-');
29+
2630
const configToFilename = (item: AddDeviceResponseConfig): string =>
27-
`${item.network_name.toLowerCase().replaceAll(' ', '-')}.txt`;
31+
`${configToLocationName(item)}.conf`;
2832

2933
type Props = { data: AddDeviceResponse; privateKey?: string };
3034

@@ -33,9 +37,9 @@ export const ModalDeviceConfigSection = ({ data: response, privateKey }: Props)
3337
const { writeToClipboard } = useClipboard();
3438
const selectOptions = useMemo(
3539
() =>
36-
response.configs.map(
37-
(item): SelectOption<AddDeviceResponseConfig> => configToOption(item),
38-
),
40+
response.configs
41+
.filter((item) => item.location_mfa_mode === LocationMfaMode.Disabled)
42+
.map((item): SelectOption<AddDeviceResponseConfig> => configToOption(item)),
3943
[response.configs],
4044
);
4145
const [selectedOption, setSelected] =
@@ -58,19 +62,23 @@ export const ModalDeviceConfigSection = ({ data: response, privateKey }: Props)
5862
}, [selectedOption, privateKey]);
5963

6064
const handleDownloadSelected = useCallback(() => {
61-
downloadText(clipboardConfig, 'conf');
62-
}, [clipboardConfig]);
65+
if (!selectedOption) return;
66+
downloadText(clipboardConfig, configToLocationName(selectedOption.value), 'conf');
67+
}, [clipboardConfig, selectedOption]);
6368

6469
const handleDownloadAll = useCallback(async () => {
6570
if (!response) return;
71+
const nonMfaConfigs = response.configs.filter(
72+
(c) => c.location_mfa_mode === LocationMfaMode.Disabled,
73+
);
6674
let data: AddDeviceResponseConfig[] = [];
6775
if (isPresent(privateKey)) {
68-
data = response.configs.map((c) => ({
76+
data = nonMfaConfigs.map((c) => ({
6977
...c,
7078
config: c.config.replace('YOUR_PRIVATE_KEY', privateKey as string),
7179
}));
7280
} else {
73-
data = response.configs;
81+
data = nonMfaConfigs;
7482
}
7583
const zip = new ZipArchive();
7684
for (const item of data) {

0 commit comments

Comments
 (0)