Browse Source

be able to update cidr

pull/1572/head
Bernd Storath 3 months ago
parent
commit
f138047668
  1. 7
      src/app/components/ui/ChooseLang.vue
  2. 7
      src/app/pages/setup/1.vue
  3. 1
      src/package.json
  4. 19
      src/pnpm-lock.yaml
  5. 3
      src/server/api/setup/migrate.post.ts
  6. 32
      src/server/utils/WireGuard.ts
  7. 4
      src/server/utils/types.ts
  8. 36
      src/services/database/lowdb.ts
  9. 3
      src/services/database/repositories/client.ts

7
src/app/components/ui/ChooseLang.vue

@ -33,13 +33,12 @@
<script setup lang="ts">
// TODO: improve
const { locale, locales } = useI18n();
const emit = defineEmits(['update:lang']);
const { locales, locale, setLocale } = useI18n();
const langProxy = ref(locale);
watch(langProxy, (newVal) => {
emit('update:lang', newVal);
watchEffect(() => {
setLocale(langProxy.value);
});
const langs = locales.value.sort((a, b) => a.code.localeCompare(b.code));

7
src/app/pages/setup/1.vue

@ -4,7 +4,7 @@
{{ $t('setup.messageSetupLanguage') }}
</p>
<div class="mb-8 flex justify-center">
<UiChooseLang @update:lang="handleEventUpdateLang" />
<UiChooseLang />
</div>
<div><BaseButton @click="nextStep">Continue</BaseButton></div>
</div>
@ -15,11 +15,6 @@ definePageMeta({
layout: 'setup',
});
const { setLocale } = useI18n();
function handleEventUpdateLang(value: string) {
setLocale(value);
}
const setupStore = useSetupStore();
setupStore.setStep(1);

1
src/package.json

@ -29,6 +29,7 @@
"crc-32": "^1.2.2",
"debug": "^4.4.0",
"ip-bigint": "^8.2.0",
"is-cidr": "^5.1.0",
"is-ip": "^5.0.1",
"js-sha256": "^0.11.0",
"lowdb": "^7.0.1",

19
src/pnpm-lock.yaml

@ -44,6 +44,9 @@ importers:
ip-bigint:
specifier: ^8.2.0
version: 8.2.0
is-cidr:
specifier: ^5.1.0
version: 5.1.0
is-ip:
specifier: ^5.0.1
version: 5.0.1
@ -1709,6 +1712,10 @@ packages:
resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==}
engines: {node: '>=8'}
[email protected]:
resolution: {integrity: sha512-ekKcVp+iRB9zlKFXyx7io7nINgb0oRjgRdXNEodp1OuxRui8FXr/CA40Tz1voWUp9DPPrMyQKy01vJhDo4N1lw==}
engines: {node: '>=14'}
[email protected]:
resolution: {integrity: sha512-OLeM9EOXybbhMsGGBNRLCMjn8e+wFOXARIShF/sZwmJLsxWywqfE0By4BMftT6BFWpbcETWpW7TfM2KGCtrZDg==}
engines: {node: '>=18'}
@ -2635,6 +2642,10 @@ packages:
resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
engines: {node: '>=6'}
[email protected]:
resolution: {integrity: sha512-OkVS+Ht2ssF27d48gZdB+ho1yND1VbkJRKKS6Pc1/Cw7uqkd9IOJg8/bTwBDQL6tfBhSdguPRnlGiE8pU/X5NQ==}
engines: {node: '>=14'}
[email protected]:
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
engines: {node: '>= 0.4'}
@ -6487,6 +6498,10 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
ip-regex: 5.0.0
[email protected]:
dependencies:
ip-bigint: 8.2.0
@ -7490,6 +7505,10 @@ snapshots:
dependencies:
builtin-modules: 3.3.0
[email protected]:
dependencies:
cidr-regex: 4.1.1
[email protected]:
dependencies:
hasown: 2.0.2

3
src/server/api/setup/migrate.post.ts

@ -61,11 +61,10 @@ export default defineEventHandler(async (event) => {
clients: {} as Database['clients'],
};
for (const [oldId, oldClient] of Object.entries(oldConfig.clients)) {
for (const oldClient of Object.values(oldConfig.clients)) {
const address6 = nextIPv6(db.system, db.clients);
await Database.client.create({
id: oldId,
address4: oldClient.address,
enabled: oldClient.enabled,
name: oldClient.name,

32
src/server/utils/WireGuard.ts

@ -1,8 +1,8 @@
import fs from 'node:fs/promises';
import debug from 'debug';
import crypto from 'node:crypto';
import QRCode from 'qrcode';
import CRC32 from 'crc-32';
import isCidr from 'is-cidr';
import type {
CreateClient,
@ -142,11 +142,7 @@ class WireGuard {
const address6 = nextIPv6(system, clients);
// Create Client
const id = crypto.randomUUID();
const client: CreateClient = {
id,
name,
address4,
address6,
@ -229,7 +225,31 @@ class WireGuard {
address4: string;
address6: string;
}) {
// TOOD: validate, change
// TODO: be able to revert if error
if (!isCidr(address4) || !isCidr(address6)) {
throw new Error('Invalid CIDR');
}
await Database.system.updateAddressRange(address4, address6);
const systems = await Database.system.get();
const clients = await Database.client.findAll();
for (const _client of Object.values(clients)) {
const clients = await Database.client.findAll();
const client = structuredClone(_client) as DeepWriteable<typeof _client>;
client.address4 = nextIPv4(systems, clients);
client.address6 = nextIPv6(systems, clients);
await Database.client.update(client.id, {
...client,
});
}
await this.saveConfig();
}
// TODO: reimplement database restore

4
src/server/utils/types.ts

@ -245,3 +245,7 @@ export function validateZod<T>(
}
};
}
export type DeepWriteable<T> = {
-readonly [P in keyof T]: DeepWriteable<T[P]>;
};

36
src/services/database/lowdb.ts

@ -1,20 +1,21 @@
import crypto from 'node:crypto';
import debug from 'debug';
import { JSONFilePreset } from 'lowdb/node';
import type { Low } from 'lowdb';
import type { DeepReadonly } from 'vue';
import { parseCidr } from 'cidr-tools';
import { stringifyIp } from 'ip-bigint';
import {
DatabaseProvider,
DatabaseError,
DEFAULT_DATABASE,
} from './repositories/database';
import { JSONFilePreset } from 'lowdb/node';
import type { Low } from 'lowdb';
import { UserRepository, type User } from './repositories/user';
import type { Database } from './repositories/database';
import { migrationRunner } from './migrations';
import {
ClientRepository,
type Client,
type UpdateClient,
type CreateClient,
type OneTimeLink,
@ -27,7 +28,6 @@ import {
type WGHooks,
} from './repositories/system';
import { SetupRepository, type Steps } from './repositories/setup';
import type { DeepReadonly } from 'vue';
const DEBUG = debug('LowDB');
@ -123,6 +123,27 @@ class LowDBSystem extends SystemRepository {
v.system.hooks = hooks;
});
}
/**
* updates the address range and the interface address
*/
async updateAddressRange(address4Range: string, address6Range: string) {
DEBUG('Update Address Range');
const cidr4 = parseCidr(address4Range);
const cidr6 = parseCidr(address6Range);
this.#db.update((v) => {
v.system.userConfig.address4Range = address4Range;
v.system.userConfig.address6Range = address6Range;
v.system.interface.address4 = stringifyIp({
number: cidr4.start + 1n,
version: 4,
});
v.system.interface.address6 = stringifyIp({
number: cidr6.start + 1n,
version: 6,
});
});
}
}
class LowDBUser extends UserRepository {
@ -211,10 +232,11 @@ class LowDBClient extends ClientRepository {
async create(client: CreateClient) {
DEBUG('Create Client');
const id = crypto.randomUUID();
const now = new Date().toISOString();
const newClient: Client = { ...client, createdAt: now, updatedAt: now };
const newClient = { ...client, createdAt: now, updatedAt: now, id };
await this.#db.update((data) => {
data.clients[client.id] = newClient;
data.clients[id] = newClient;
});
}

3
src/services/database/repositories/client.ts

@ -28,7 +28,8 @@ export type Client = {
mtu: number;
};
export type CreateClient = Omit<Client, 'createdAt' | 'updatedAt'>;
export type CreateClient = Omit<Client, 'createdAt' | 'updatedAt' | 'id'>;
export type UpdateClient = Omit<
Client,
| 'createdAt'

Loading…
Cancel
Save