diff --git a/src/app/pages/clients/[id].vue b/src/app/pages/clients/[id].vue index 4b7a9575..4c82b44e 100644 --- a/src/app/pages/clients/[id].vue +++ b/src/app/pages/clients/[id].vue @@ -71,6 +71,13 @@ :label="$t('general.persistentKeepalive')" /> + + {{ $t('form.hooks') }} + + + + + {{ $t('form.actions') }} diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 79545cf2..a9de313a 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -118,7 +118,8 @@ "sectionGeneral": "General", "sectionAdvanced": "Advanced", "noItems": "No items", - "add": "Add" + "add": "Add", + "hooks": "Hooks" }, "admin": { "general": { diff --git a/src/server/api/setup/migrate.post.ts b/src/server/api/setup/migrate.post.ts index febd0702..dfcfe9aa 100644 --- a/src/server/api/setup/migrate.post.ts +++ b/src/server/api/setup/migrate.post.ts @@ -28,6 +28,10 @@ export default defineSetupEventHandler('migrate', async ({ event }) => { createdAt: z.string(), updatedAt: z.string(), enabled: z.boolean(), + preUp: z.string(), + postUp: z.string(), + preDown: z.string(), + postDown: z.string(), }) ), }); @@ -68,6 +72,10 @@ export default defineSetupEventHandler('migrate', async ({ event }) => { ...clientConfig, ipv4Address: clientConfig.address, ipv6Address, + preUp: clientConfig.preUp, + postUp: clientConfig.postUp, + preDown: clientConfig.preDown, + postDown: clientConfig.postDown }); } diff --git a/src/server/database/migrations/0000_short_skin.sql b/src/server/database/migrations/0000_short_skin.sql index 38283554..2d8b9d5d 100644 --- a/src/server/database/migrations/0000_short_skin.sql +++ b/src/server/database/migrations/0000_short_skin.sql @@ -12,6 +12,10 @@ CREATE TABLE `clients_table` ( `server_allowed_ips` text NOT NULL, `persistent_keepalive` integer NOT NULL, `mtu` integer NOT NULL, + `pre_up` text, + `post_up` text, + `pre_down` text, + `post_down` text, `dns` text NOT NULL, `enabled` integer NOT NULL, `created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL, diff --git a/src/server/database/migrations/meta/0000_snapshot.json b/src/server/database/migrations/meta/0000_snapshot.json index 1b217e6c..ce28c7e8 100644 --- a/src/server/database/migrations/meta/0000_snapshot.json +++ b/src/server/database/migrations/meta/0000_snapshot.json @@ -98,6 +98,34 @@ "notNull": true, "autoincrement": false }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, "dns": { "name": "dns", "type": "text", diff --git a/src/server/database/migrations/meta/0001_snapshot.json b/src/server/database/migrations/meta/0001_snapshot.json index f04104fa..989c309c 100644 --- a/src/server/database/migrations/meta/0001_snapshot.json +++ b/src/server/database/migrations/meta/0001_snapshot.json @@ -98,6 +98,34 @@ "notNull": true, "autoincrement": false }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, "dns": { "name": "dns", "type": "text", diff --git a/src/server/database/repositories/client/schema.ts b/src/server/database/repositories/client/schema.ts index 882f49e6..4198aa0f 100644 --- a/src/server/database/repositories/client/schema.ts +++ b/src/server/database/repositories/client/schema.ts @@ -14,6 +14,10 @@ export const client = sqliteTable('clients_table', { name: text().notNull(), ipv4Address: text('ipv4_address').notNull().unique(), ipv6Address: text('ipv6_address').notNull().unique(), + preUp: text('pre_up'), + postUp: text('post_up'), + preDown: text('pre_down'), + postDown: text('post_down'), privateKey: text('private_key').notNull(), publicKey: text('public_key').notNull(), preSharedKey: text('pre_shared_key').notNull(), diff --git a/src/server/database/repositories/client/service.ts b/src/server/database/repositories/client/service.ts index 3cc5a2b9..91c52217 100644 --- a/src/server/database/repositories/client/service.ts +++ b/src/server/database/repositories/client/service.ts @@ -101,6 +101,10 @@ export class ClientService { const ipv4Address = nextIP(4, ipv4Cidr, clients); const ipv6Cidr = parseCidr(clientInterface.ipv6Cidr); const ipv6Address = nextIP(6, ipv6Cidr, clients); + const preUp = ''; + const postUp = ''; + const preDown = ''; + const postDown = ''; await tx .insert(client) @@ -114,6 +118,10 @@ export class ClientService { preSharedKey, ipv4Address, ipv6Address, + preUp, + postUp, + preDown, + postDown, mtu: clientConfig.defaultMtu, allowedIps: clientConfig.defaultAllowedIps, dns: clientConfig.defaultDns, @@ -145,6 +153,10 @@ export class ClientService { preSharedKey, privateKey, publicKey, + preUp, + postUp, + preDown, + postDown }: ClientCreateFromExistingType) { const clientConfig = await Database.userConfigs.get(); @@ -158,6 +170,10 @@ export class ClientService { preSharedKey, ipv4Address, ipv6Address, + preUp, + postUp, + preDown, + postDown, mtu: clientConfig.defaultMtu, allowedIps: clientConfig.defaultAllowedIps, dns: clientConfig.defaultDns, diff --git a/src/server/database/repositories/client/types.ts b/src/server/database/repositories/client/types.ts index 3be4b572..46387d68 100644 --- a/src/server/database/repositories/client/types.ts +++ b/src/server/database/repositories/client/types.ts @@ -39,6 +39,26 @@ const address6 = z .min(1, { message: t('zod.client.address6') }) .pipe(safeStringRefine); +const preUp = z + .string({ message: t('zod.client.preUp') }) + .pipe(safeStringRefine) + .nullable(); + +const postUp = z + .string({ message: t('zod.client.postUp') }) + .pipe(safeStringRefine) + .nullable(); + +const preDown = z + .string({ message: t('zod.client.preDown') }) + .pipe(safeStringRefine) + .nullable(); + +const postDown = z + .string({ message: t('zod.client.postDown') }) + .pipe(safeStringRefine) + .nullable(); + const serverAllowedIps = z.array(AddressSchema, { message: t('zod.client.serverAllowedIps'), }); @@ -57,6 +77,10 @@ export const ClientUpdateSchema = schemaForType()( expiresAt: expiresAt, ipv4Address: address4, ipv6Address: address6, + preUp: preUp, + postUp: postUp, + preDown: preDown, + postDown: postDown, allowedIps: AllowedIpsSchema, serverAllowedIps: serverAllowedIps, mtu: MtuSchema, @@ -77,6 +101,10 @@ export type ClientCreateFromExistingType = Pick< | 'name' | 'ipv4Address' | 'ipv6Address' + | 'preUp' + | 'postUp' + | 'preDown' + | 'postDown' | 'privateKey' | 'preSharedKey' | 'publicKey' diff --git a/src/server/database/repositories/userConfig/types.ts b/src/server/database/repositories/userConfig/types.ts index f8805d5f..e50527e9 100644 --- a/src/server/database/repositories/userConfig/types.ts +++ b/src/server/database/repositories/userConfig/types.ts @@ -26,6 +26,6 @@ export const UserConfigUpdateSchema = schemaForType()( defaultPersistentKeepalive: PersistentKeepaliveSchema, defaultDns: DnsSchema, defaultAllowedIps: AllowedIpsSchema, - host: host, + host: host }) ); diff --git a/src/server/utils/wgHelper.ts b/src/server/utils/wgHelper.ts index 4b13afb7..5dc08170 100644 --- a/src/server/utils/wgHelper.ts +++ b/src/server/utils/wgHelper.ts @@ -54,6 +54,10 @@ PrivateKey = ${client.privateKey} Address = ${client.ipv4Address}/${cidr4Block}, ${client.ipv6Address}/${cidr6Block} DNS = ${client.dns.join(', ')} MTU = ${client.mtu} +PreUp = ${client.preUp} +PostUp = ${client.postUp} +PreDown = ${client.preDown} +PostDown = ${client.postDown} [Peer] PublicKey = ${wgInterface.publicKey} @@ -103,6 +107,10 @@ Endpoint = ${userConfig.host}:${userConfig.port}`; string, string, string, + string, + string, + string, + string, ]; return rawDump @@ -120,6 +128,10 @@ Endpoint = ${userConfig.host}:${userConfig.port}`; transferRx, transferTx, persistentKeepalive, + preUp, + postUp, + preDown, + postDown ] = splitLines as wgDumpLine; return { @@ -134,6 +146,10 @@ Endpoint = ${userConfig.host}:${userConfig.port}`; transferRx: Number.parseInt(transferRx), transferTx: Number.parseInt(transferTx), persistentKeepalive: persistentKeepalive, + preUp: preUp, + postUp: postUp, + preDown: preDown, + postDown: postDown }; }); },