Compare commits

...

2 Commits

Author SHA1 Message Date
Bernd Storath 93db67bab6 fix: only require metrics password if set (#1715) 2025-03-06 11:45:03 +01:00
Bernd Storath 842475f799 Fix: Cidr Change (#1712)
* only calculate ip if cidr changed

if the cidr did not change, the ip will not change to prevent ip shifts

* fix lint
2025-03-06 10:04:49 +01:00
4 changed files with 51 additions and 32 deletions
+2 -1
View File
@@ -193,7 +193,8 @@
},
"interface": {
"cidr": "CIDR",
"device": "Device"
"device": "Device",
"cidrValid": "CIDR must be valid"
},
"otl": "One Time link",
"stringMalformed": "String is malformed",
@@ -1,4 +1,3 @@
import isCidr from 'is-cidr';
import { eq, sql } from 'drizzle-orm';
import { parseCidr } from 'cidr-tools';
import { wgInterface } from './schema';
@@ -58,10 +57,18 @@ export class InterfaceService {
}
updateCidr(data: InterfaceCidrUpdateType) {
if (!isCidr(data.ipv4Cidr) || !isCidr(data.ipv6Cidr)) {
throw new Error('Invalid CIDR');
}
return this.#db.transaction(async (tx) => {
const oldCidr = await tx.query.wgInterface
.findFirst({
where: eq(wgInterface.name, 'wg0'),
columns: { ipv4Cidr: true, ipv6Cidr: true },
})
.execute();
if (!oldCidr) {
throw new Error('Interface not found');
}
await tx
.update(wgInterface)
.set(data)
@@ -74,8 +81,17 @@ export class InterfaceService {
// TODO: optimize
const clients = await tx.query.client.findMany().execute();
const nextIpv4 = nextIP(4, parseCidr(data.ipv4Cidr), clients);
const nextIpv6 = nextIP(6, parseCidr(data.ipv6Cidr), clients);
// only calculate ip if cidr has changed
let nextIpv4 = client.ipv4Address;
if (data.ipv4Cidr !== oldCidr.ipv4Cidr) {
nextIpv4 = nextIP(4, parseCidr(data.ipv4Cidr), clients);
}
let nextIpv6 = client.ipv6Address;
if (data.ipv6Cidr !== oldCidr.ipv6Cidr) {
nextIpv6 = nextIP(6, parseCidr(data.ipv6Cidr), clients);
}
await tx
.update(clientSchema)
@@ -1,5 +1,6 @@
import type { InferSelectModel } from 'drizzle-orm';
import z from 'zod';
import isCidr from 'is-cidr';
import type { wgInterface } from './schema';
export type InterfaceType = InferSelectModel<typeof wgInterface>;
@@ -22,6 +23,7 @@ const device = z
const cidr = z
.string({ message: t('zod.interface.cidr') })
.min(1, { message: t('zod.interface.cidr') })
.refine((value) => isCidr(value), { message: t('zod.interface.cidrValid') })
.pipe(safeStringRefine);
export const InterfaceUpdateSchema = schemaForType<InterfaceUpdateType>()(
+25 -25
View File
@@ -138,34 +138,27 @@ export const defineMetricsHandler = <
handler: MetricsHandler<TReq, TRes>
) => {
return defineEventHandler(async (event) => {
const auth = getHeader(event, 'Authorization');
if (!auth) {
throw createError({
statusCode: 401,
statusMessage: 'Unauthorized',
});
}
const [method, value] = auth.split(' ');
if (method !== 'Bearer' || !value) {
throw createError({
statusCode: 401,
statusMessage: 'Bearer Auth required',
});
}
const metricsConfig = await Database.general.getMetricsConfig();
if (metricsConfig[type] !== true) {
throw createError({
statusCode: 400,
statusMessage: 'Metrics not enabled',
});
}
if (metricsConfig.password) {
const auth = getHeader(event, 'Authorization');
if (!auth) {
throw createError({
statusCode: 401,
statusMessage: 'Unauthorized',
});
}
const [method, value] = auth.split(' ');
if (method !== 'Bearer' || !value) {
throw createError({
statusCode: 401,
statusMessage: 'Bearer Auth required',
});
}
const tokenValid = await isPasswordValid(value, metricsConfig.password);
if (!tokenValid) {
@@ -176,6 +169,13 @@ export const defineMetricsHandler = <
}
}
if (metricsConfig[type] !== true) {
throw createError({
statusCode: 400,
statusMessage: 'Metrics not enabled',
});
}
return await handler({ event });
});
};