diff --git a/src/app/pages/admin/interface.vue b/src/app/pages/admin/interface.vue index f926ddf0..abe99ef6 100644 --- a/src/app/pages/admin/interface.vue +++ b/src/app/pages/admin/interface.vue @@ -20,6 +20,16 @@ :label="$t('admin.interface.device')" :description="$t('admin.interface.deviceDesc')" /> + + + + + + + + + + {{ $t('form.actions') }} diff --git a/src/server/database/migrations/0002_even_iceman.sql b/src/server/database/migrations/0002_even_iceman.sql new file mode 100644 index 00000000..eeaec4cd --- /dev/null +++ b/src/server/database/migrations/0002_even_iceman.sql @@ -0,0 +1,10 @@ +ALTER TABLE `interfaces_table` ADD `jC` integer DEFAULT 7 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `jMin` integer DEFAULT 50 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `jMax` integer DEFAULT 1000 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `s1` integer DEFAULT 68 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `s2` integer DEFAULT 149 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `h1` integer DEFAULT 1106457265 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `h2` integer DEFAULT 249455488 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `h3` integer DEFAULT 1209847463 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `h4` integer DEFAULT 1646644382 NOT NULL;--> statement-breakpoint +ALTER TABLE `interfaces_table` ADD `i1` text; \ No newline at end of file diff --git a/src/server/database/migrations/meta/0002_snapshot.json b/src/server/database/migrations/meta/0002_snapshot.json new file mode 100644 index 00000000..ccba2dbf --- /dev/null +++ b/src/server/database/migrations/meta/0002_snapshot.json @@ -0,0 +1,819 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "2fd3104a-c62a-4575-89ab-5e002fae9e69", + "prevId": "78de2e52-c4a8-4900-86c5-92f34739623a", + "tables": { + "clients_table": { + "name": "clients_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "interface_id": { + "name": "interface_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv4_address": { + "name": "ipv4_address", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv6_address": { + "name": "ipv6_address", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_shared_key": { + "name": "pre_shared_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allowed_ips": { + "name": "allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "server_allowed_ips": { + "name": "server_allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "persistent_keepalive": { + "name": "persistent_keepalive", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mtu": { + "name": "mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "dns": { + "name": "dns", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "server_endpoint": { + "name": "server_endpoint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "clients_table_ipv4_address_unique": { + "name": "clients_table_ipv4_address_unique", + "columns": [ + "ipv4_address" + ], + "isUnique": true + }, + "clients_table_ipv6_address_unique": { + "name": "clients_table_ipv6_address_unique", + "columns": [ + "ipv6_address" + ], + "isUnique": true + } + }, + "foreignKeys": { + "clients_table_user_id_users_table_id_fk": { + "name": "clients_table_user_id_users_table_id_fk", + "tableFrom": "clients_table", + "tableTo": "users_table", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "clients_table_interface_id_interfaces_table_name_fk": { + "name": "clients_table_interface_id_interfaces_table_name_fk", + "tableFrom": "clients_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "interface_id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "general_table": { + "name": "general_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "setup_step": { + "name": "setup_step", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_password": { + "name": "session_password", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_timeout": { + "name": "session_timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_prometheus": { + "name": "metrics_prometheus", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_json": { + "name": "metrics_json", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_password": { + "name": "metrics_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "hooks_table": { + "name": "hooks_table", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "hooks_table_id_interfaces_table_name_fk": { + "name": "hooks_table_id_interfaces_table_name_fk", + "tableFrom": "hooks_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "interfaces_table": { + "name": "interfaces_table", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "device": { + "name": "device", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv4_cidr": { + "name": "ipv4_cidr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv6_cidr": { + "name": "ipv6_cidr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mtu": { + "name": "mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "jC": { + "name": "jC", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 7 + }, + "jMin": { + "name": "jMin", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 50 + }, + "jMax": { + "name": "jMax", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1000 + }, + "s1": { + "name": "s1", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 68 + }, + "s2": { + "name": "s2", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 149 + }, + "h1": { + "name": "h1", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1106457265 + }, + "h2": { + "name": "h2", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 249455488 + }, + "h3": { + "name": "h3", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1209847463 + }, + "h4": { + "name": "h4", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1646644382 + }, + "i1": { + "name": "i1", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "interfaces_table_port_unique": { + "name": "interfaces_table_port_unique", + "columns": [ + "port" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "one_time_links_table": { + "name": "one_time_links_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "one_time_link": { + "name": "one_time_link", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "one_time_links_table_one_time_link_unique": { + "name": "one_time_links_table_one_time_link_unique", + "columns": [ + "one_time_link" + ], + "isUnique": true + } + }, + "foreignKeys": { + "one_time_links_table_id_clients_table_id_fk": { + "name": "one_time_links_table_id_clients_table_id_fk", + "tableFrom": "one_time_links_table", + "tableTo": "clients_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users_table": { + "name": "users_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "totp_key": { + "name": "totp_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "totp_verified": { + "name": "totp_verified", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "users_table_username_unique": { + "name": "users_table_username_unique", + "columns": [ + "username" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_configs_table": { + "name": "user_configs_table", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "default_mtu": { + "name": "default_mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_persistent_keepalive": { + "name": "default_persistent_keepalive", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_dns": { + "name": "default_dns", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_allowed_ips": { + "name": "default_allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "user_configs_table_id_interfaces_table_name_fk": { + "name": "user_configs_table_id_interfaces_table_name_fk", + "tableFrom": "user_configs_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/src/server/database/migrations/meta/_journal.json b/src/server/database/migrations/meta/_journal.json index b3ee612d..01a99aaf 100644 --- a/src/server/database/migrations/meta/_journal.json +++ b/src/server/database/migrations/meta/_journal.json @@ -15,6 +15,13 @@ "when": 1748427001203, "tag": "0001_classy_the_stranger", "breakpoints": true + }, + { + "idx": 2, + "version": "6", + "when": 1757610568979, + "tag": "0002_even_iceman", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/server/database/repositories/interface/schema.ts b/src/server/database/repositories/interface/schema.ts index 6f84bc69..cf0836d8 100644 --- a/src/server/database/repositories/interface/schema.ts +++ b/src/server/database/repositories/interface/schema.ts @@ -13,6 +13,16 @@ export const wgInterface = sqliteTable('interfaces_table', { ipv4Cidr: text('ipv4_cidr').notNull(), ipv6Cidr: text('ipv6_cidr').notNull(), mtu: int().notNull(), + jC: int().notNull().default(7), + jMin: int().notNull().default(50), + jMax: int().notNull().default(1000), + s1: int().notNull().default(68), + s2: int().notNull().default(149), + h1: int().notNull().default(1106457265), + h2: int().notNull().default(249455488), + h3: int().notNull().default(1209847463), + h4: int().notNull().default(1646644382), + i1: text('i1'), // does nothing yet enabled: int({ mode: 'boolean' }).notNull(), createdAt: text('created_at') diff --git a/src/server/database/repositories/interface/types.ts b/src/server/database/repositories/interface/types.ts index 5d604c1e..09a7f940 100644 --- a/src/server/database/repositories/interface/types.ts +++ b/src/server/database/repositories/interface/types.ts @@ -32,6 +32,16 @@ export const InterfaceUpdateSchema = schemaForType()( ipv6Cidr: cidr, mtu: MtuSchema, port: PortSchema, + jC: JcSchema, + jMin: JminSchema, + jMax: JmaxSchema, + s1: S1Schema, + s2: S2Schema, + h1: HSchema, + h2: HSchema, + h3: HSchema, + h4: HSchema, + i1: ISchema, device: device, enabled: EnabledSchema, }) diff --git a/src/server/utils/types.ts b/src/server/utils/types.ts index 9d00eacb..3a4a976c 100644 --- a/src/server/utils/types.ts +++ b/src/server/utils/types.ts @@ -20,6 +20,23 @@ export const safeStringRefine = z export const EnabledSchema = z.boolean({ message: t('zod.enabled') }); +export const JcSchema = z.number().min(1).max(128); + +export const JminSchema = z.number().max(1279); + +export const JmaxSchema = z.number().max(1280); + +export const S1Schema = z.number().max(1132); + +export const S2Schema = z.number().max(1188); + +export const HSchema = z.number().min(5).max(2147483647); + +const ISchema = z.preprocess( + (val) => (val === '' ? null : val), + z.string().nullable() +); + export const MtuSchema = z .number({ message: t('zod.mtu') }) .min(1280, { message: t('zod.mtu') }) diff --git a/src/server/utils/wgHelper.ts b/src/server/utils/wgHelper.ts index e424fcc0..f56aa7dd 100644 --- a/src/server/utils/wgHelper.ts +++ b/src/server/utils/wgHelper.ts @@ -71,6 +71,16 @@ PrivateKey = ${wgInterface.privateKey} Address = ${address} ListenPort = ${wgInterface.port} MTU = ${wgInterface.mtu} +Jc = ${wgInterface.jC} +Jmin = ${wgInterface.jMin} +Jmax = ${wgInterface.jMax} +S1 = ${wgInterface.s1} +S2 = ${wgInterface.s2} +H1 = ${wgInterface.h1} +H2 = ${wgInterface.h2} +H3 = ${wgInterface.h3} +H4 = ${wgInterface.h4} +${wgInterface.i1 ? `I1 = ${wgInterface.i1}` : ''} PreUp = ${iptablesTemplate(hooks.preUp, wgInterface)} PostUp = ${iptablesTemplate(hooks.postUp, wgInterface)} PreDown = ${iptablesTemplate(hooks.preDown, wgInterface)} @@ -109,6 +119,16 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`; PrivateKey = ${client.privateKey} Address = ${address} MTU = ${client.mtu} +Jc = ${wgInterface.jC} +Jmin = ${wgInterface.jMin} +Jmax = ${wgInterface.jMax} +S1 = ${wgInterface.s1} +S2 = ${wgInterface.s2} +H1 = ${wgInterface.h1} +H2 = ${wgInterface.h2} +H3 = ${wgInterface.h3} +H4 = ${wgInterface.h4} +${wgInterface.i1 ? `I1 = ${wgInterface.i1}` : ''} ${extraLines.length ? `${extraLines.join('\n')}\n` : ''} [Peer] PublicKey = ${wgInterface.publicKey}