Browse Source

be able to change dns. implement global override

pull/1720/head
Bernd Storath 5 months ago
parent
commit
bfdc57a55a
  1. 68
      src/app/components/Form/NullArrayField.vue
  2. 2
      src/app/pages/admin/config.vue
  3. 27
      src/app/pages/clients/[id].vue
  4. 8
      src/i18n/locales/en.json
  5. 2
      src/server/database/migrations/0000_short_skin.sql
  6. 4
      src/server/database/migrations/meta/0000_snapshot.json
  7. 6
      src/server/database/migrations/meta/0001_snapshot.json
  8. 4
      src/server/database/migrations/meta/_journal.json
  9. 4
      src/server/database/repositories/client/schema.ts
  10. 1
      src/server/database/repositories/client/service.ts
  11. 2
      src/server/database/repositories/client/types.ts
  12. 2
      src/server/utils/wgHelper.ts

68
src/app/components/Form/NullArrayField.vue

@ -0,0 +1,68 @@
<template>
<div class="flex flex-col gap-2">
<div v-if="data === null">
{{ emptyText || $t('form.nullNoItems') }}
</div>
<div v-for="(item, i) in data" v-else :key="i">
<div class="mt-1 flex flex-row gap-1">
<input
:value="item"
:name="name"
type="text"
class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
@input="update($event, i)"
/>
<BaseButton
as="input"
type="button"
class="rounded-lg"
value="-"
@click="del(i)"
/>
</div>
</div>
<div class="mt-2">
<BaseButton
as="input"
type="button"
class="rounded-lg"
:value="$t('form.add')"
@click="add"
/>
</div>
</div>
</template>
<script lang="ts" setup>
const data = defineModel<string[] | null>();
defineProps<{ emptyText?: string[]; name: string }>();
function update(e: Event, i: number) {
const v = (e.target as HTMLInputElement).value;
if (!data.value) {
return;
}
data.value[i] = v;
}
function add() {
if (data.value === undefined) {
return;
}
if (data.value === null) {
data.value = [''];
} else {
data.value.push('');
}
}
function del(i: number) {
if (!data.value) {
return;
}
data.value.splice(i, 1);
if (data.value.length === 0) {
data.value = null;
}
}
</script>

2
src/app/pages/admin/config.vue

@ -27,7 +27,7 @@
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormHeading :description="$t('admin.config.dnsDesc')">{{ <FormHeading :description="$t('admin.config.dnsDesc')">{{
$t('admin.config.dns') $t('general.dns')
}}</FormHeading> }}</FormHeading>
<FormArrayField v-model="data.defaultDns" name="defaultDns" /> <FormArrayField v-model="data.defaultDns" name="defaultDns" />
</FormGroup> </FormGroup>

27
src/app/pages/clients/[id].vue

@ -41,21 +41,26 @@
/> />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormHeading :description="$t('client.allowedIpsDesc')">{{ <FormHeading :description="$t('client.allowedIpsDesc')">
$t('general.allowedIps') {{ $t('general.allowedIps') }}
}}</FormHeading> </FormHeading>
<FormArrayField v-model="data.allowedIps" name="allowedIps" /> <FormArrayField v-model="data.allowedIps" name="allowedIps" />
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormHeading :description="$t('client.serverAllowedIpsDesc')">{{ <FormHeading :description="$t('client.serverAllowedIpsDesc')">
$t('client.serverAllowedIps') {{ $t('client.serverAllowedIps') }}
}}</FormHeading> </FormHeading>
<FormArrayField <FormArrayField
v-model="data.serverAllowedIps" v-model="data.serverAllowedIps"
name="serverAllowedIps" name="serverAllowedIps"
/> />
</FormGroup> </FormGroup>
<FormGroup></FormGroup> <FormGroup>
<FormHeading :description="$t('client.dnsDesc')">
{{ $t('general.dns') }}
</FormHeading>
<FormNullArrayField v-model="data.dns" name="dns" />
</FormGroup>
<FormGroup> <FormGroup>
<FormHeading>{{ $t('form.sectionAdvanced') }}</FormHeading> <FormHeading>{{ $t('form.sectionAdvanced') }}</FormHeading>
<FormNumberField <FormNumberField
@ -142,8 +147,12 @@ const _submit = useSubmit(
method: 'post', method: 'post',
}, },
{ {
revert: async () => { revert: async (success) => {
await navigateTo('/'); if (success) {
await navigateTo('/');
} else {
await revert();
}
}, },
} }
); );

8
src/i18n/locales/en.json

@ -25,6 +25,7 @@
"updatePassword": "Update Password", "updatePassword": "Update Password",
"mtu": "MTU", "mtu": "MTU",
"allowedIps": "Allowed IPs", "allowedIps": "Allowed IPs",
"dns": "DNS",
"persistentKeepalive": "Persistent Keepalive", "persistentKeepalive": "Persistent Keepalive",
"logout": "Logout", "logout": "Logout",
"continue": "Continue", "continue": "Continue",
@ -101,7 +102,8 @@
"persistentKeepaliveDesc": "Sets the interval (in seconds) for keep-alive packets. 0 disables it", "persistentKeepaliveDesc": "Sets the interval (in seconds) for keep-alive packets. 0 disables it",
"hooks": "Hooks", "hooks": "Hooks",
"hooksDescription": "Hooks only work with wg-quick", "hooksDescription": "Hooks only work with wg-quick",
"hooksLeaveEmpty": "Only for wg-quick. Otherwise, leave it empty" "hooksLeaveEmpty": "Only for wg-quick. Otherwise, leave it empty",
"dnsDesc": "DNS server clients will use (overrides global config)"
}, },
"dialog": { "dialog": {
"change": "Change", "change": "Change",
@ -121,6 +123,7 @@
"sectionGeneral": "General", "sectionGeneral": "General",
"sectionAdvanced": "Advanced", "sectionAdvanced": "Advanced",
"noItems": "No items", "noItems": "No items",
"nullNoItems": "No items. Using global config",
"add": "Add" "add": "Add"
}, },
"admin": { "admin": {
@ -140,8 +143,7 @@
"hostDesc": "Public hostname clients will connect to (invalidates config)", "hostDesc": "Public hostname clients will connect to (invalidates config)",
"portDesc": "Public UDP port clients will connect to (invalidates config)", "portDesc": "Public UDP port clients will connect to (invalidates config)",
"allowedIpsDesc": "Allowed IPs clients will use (invalidates config)", "allowedIpsDesc": "Allowed IPs clients will use (invalidates config)",
"dns": "DNS", "dnsDesc": "DNS server clients will use (global config)",
"dnsDesc": "DNS server clients will use (invalidates config)",
"mtuDesc": "MTU clients will use (invalidates config)", "mtuDesc": "MTU clients will use (invalidates config)",
"persistentKeepaliveDesc": "Interval in seconds to send keepalives to the server. 0 = disabled (invalidates config)" "persistentKeepaliveDesc": "Interval in seconds to send keepalives to the server. 0 = disabled (invalidates config)"
}, },

2
src/server/database/migrations/0000_short_skin.sql

@ -16,7 +16,7 @@ CREATE TABLE `clients_table` (
`server_allowed_ips` text NOT NULL, `server_allowed_ips` text NOT NULL,
`persistent_keepalive` integer NOT NULL, `persistent_keepalive` integer NOT NULL,
`mtu` integer NOT NULL, `mtu` integer NOT NULL,
`dns` text NOT NULL, `dns` text,
`enabled` integer NOT NULL, `enabled` integer NOT NULL,
`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL, `created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,
`updated_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL, `updated_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,

4
src/server/database/migrations/meta/0000_snapshot.json

@ -1,7 +1,7 @@
{ {
"version": "6", "version": "6",
"dialect": "sqlite", "dialect": "sqlite",
"id": "383501e4-f8de-4413-847f-a9082f6dc398", "id": "80307290-b752-4fc4-8ba4-c6d39222c7f5",
"prevId": "00000000-0000-0000-0000-000000000000", "prevId": "00000000-0000-0000-0000-000000000000",
"tables": { "tables": {
"clients_table": { "clients_table": {
@ -134,7 +134,7 @@
"name": "dns", "name": "dns",
"type": "text", "type": "text",
"primaryKey": false, "primaryKey": false,
"notNull": true, "notNull": false,
"autoincrement": false "autoincrement": false
}, },
"enabled": { "enabled": {

6
src/server/database/migrations/meta/0001_snapshot.json

@ -1,6 +1,6 @@
{ {
"id": "bf316694-e2ce-4e29-bd66-ce6c0a9d3c90", "id": "241a0a75-03d1-4b39-9a13-e7b1b621e8b2",
"prevId": "383501e4-f8de-4413-847f-a9082f6dc398", "prevId": "80307290-b752-4fc4-8ba4-c6d39222c7f5",
"version": "6", "version": "6",
"dialect": "sqlite", "dialect": "sqlite",
"tables": { "tables": {
@ -134,7 +134,7 @@
"name": "dns", "name": "dns",
"type": "text", "type": "text",
"primaryKey": false, "primaryKey": false,
"notNull": true, "notNull": false,
"autoincrement": false "autoincrement": false
}, },
"enabled": { "enabled": {

4
src/server/database/migrations/meta/_journal.json

@ -5,14 +5,14 @@
{ {
"idx": 0, "idx": 0,
"version": "6", "version": "6",
"when": 1741335144499, "when": 1741354212954,
"tag": "0000_short_skin", "tag": "0000_short_skin",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 1, "idx": 1,
"version": "6", "version": "6",
"when": 1741335153054, "when": 1741354219144,
"tag": "0001_classy_the_stranger", "tag": "0001_classy_the_stranger",
"breakpoints": true "breakpoints": true
} }

4
src/server/database/repositories/client/schema.ts

@ -3,6 +3,8 @@ import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { oneTimeLink, user } from '../../schema'; import { oneTimeLink, user } from '../../schema';
/** null means use value from userConfig */
export const client = sqliteTable('clients_table', { export const client = sqliteTable('clients_table', {
id: int().primaryKey({ autoIncrement: true }), id: int().primaryKey({ autoIncrement: true }),
userId: int('user_id') userId: int('user_id')
@ -28,7 +30,7 @@ export const client = sqliteTable('clients_table', {
.notNull(), .notNull(),
persistentKeepalive: int('persistent_keepalive').notNull(), persistentKeepalive: int('persistent_keepalive').notNull(),
mtu: int().notNull(), mtu: int().notNull(),
dns: text({ mode: 'json' }).$type<string[]>().notNull(), dns: text({ mode: 'json' }).$type<string[]>(),
enabled: int({ mode: 'boolean' }).notNull(), enabled: int({ mode: 'boolean' }).notNull(),
createdAt: text('created_at') createdAt: text('created_at')
.notNull() .notNull()

1
src/server/database/repositories/client/service.ts

@ -116,7 +116,6 @@ export class ClientService {
ipv6Address, ipv6Address,
mtu: clientConfig.defaultMtu, mtu: clientConfig.defaultMtu,
allowedIps: clientConfig.defaultAllowedIps, allowedIps: clientConfig.defaultAllowedIps,
dns: clientConfig.defaultDns,
persistentKeepalive: clientConfig.defaultPersistentKeepalive, persistentKeepalive: clientConfig.defaultPersistentKeepalive,
serverAllowedIps: [], serverAllowedIps: [],
enabled: true, enabled: true,

2
src/server/database/repositories/client/types.ts

@ -65,7 +65,7 @@ export const ClientUpdateSchema = schemaForType<UpdateClientType>()(
serverAllowedIps: serverAllowedIps, serverAllowedIps: serverAllowedIps,
mtu: MtuSchema, mtu: MtuSchema,
persistentKeepalive: PersistentKeepaliveSchema, persistentKeepalive: PersistentKeepaliveSchema,
dns: DnsSchema, dns: DnsSchema.nullable(),
}) })
); );

2
src/server/utils/wgHelper.ts

@ -59,7 +59,7 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`;
return `[Interface] return `[Interface]
PrivateKey = ${client.privateKey} PrivateKey = ${client.privateKey}
Address = ${client.ipv4Address}/${cidr4Block}, ${client.ipv6Address}/${cidr6Block} Address = ${client.ipv4Address}/${cidr4Block}, ${client.ipv6Address}/${cidr6Block}
DNS = ${client.dns.join(', ')} DNS = ${(client.dns ?? userConfig.defaultDns).join(', ')}
MTU = ${client.mtu} MTU = ${client.mtu}
${hookLines.length ? `${hookLines.join('\n')}\n` : ''} ${hookLines.length ? `${hookLines.join('\n')}\n` : ''}
[Peer] [Peer]

Loading…
Cancel
Save