Browse Source

start refactoring

pull/1864/head
Bernd Storath 3 months ago
parent
commit
a88e36319b
  1. 27
      src/eslint.config.js
  2. 11
      src/eslint.config.mjs
  3. 5
      src/server/database/repositories/client/schema.ts
  4. 8
      src/server/routes/metrics/prometheus.get.ts
  5. 4
      src/server/utils/Database.ts
  6. 13
      src/server/utils/WireGuard.ts
  7. 9
      src/server/utils/cmd.ts
  8. 10
      src/server/utils/handler.ts
  9. 15
      src/server/utils/ip.ts
  10. 2
      src/server/utils/release.ts
  11. 7
      src/server/utils/template.ts
  12. 95
      src/server/utils/types.ts
  13. 2
      src/server/utils/wgHelper.ts
  14. 2
      src/shared/utils/permissions.ts

27
src/eslint.config.js

@ -0,0 +1,27 @@
// @ts-check
import eslintConfigPrettier from 'eslint-config-prettier';
import withNuxt from './.nuxt/eslint.config.mjs';
export default withNuxt([
{
rules: {
'import/order': 'warn',
},
},
eslintConfigPrettier,
]).override('nuxt/typescript/rules', {
rules: {
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowAny: false,
allowBoolean: true,
allowNever: false,
allowNullish: false,
allowNumber: true,
allowRegExp: false,
},
],
},
});

11
src/eslint.config.mjs

@ -1,11 +0,0 @@
import eslintConfigPrettier from 'eslint-config-prettier';
import withNuxt from './.nuxt/eslint.config.mjs';
export default withNuxt([
{
rules: {
'import/order': 'warn',
},
},
eslintConfigPrettier,
]);

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

@ -43,10 +43,7 @@ export const client = sqliteTable('clients_table', {
});
export const clientsRelations = relations(client, ({ one }) => ({
oneTimeLink: one(oneTimeLink, {
fields: [client.id],
references: [oneTimeLink.id],
}),
oneTimeLink: one(oneTimeLink),
user: one(user, {
fields: [client.userId],
references: [user.id],

8
src/server/routes/metrics/prometheus.get.ts

@ -14,7 +14,7 @@ async function getPrometheusResponse() {
const wireguardLatestHandshakeSeconds = [];
for (const client of clients) {
wireguardPeerCount++;
if (client.enabled === true) {
if (client.enabled) {
wireguardEnabledPeersCount++;
}
@ -55,15 +55,15 @@ async function getPrometheusResponse() {
'',
'# HELP wireguard_sent_bytes Bytes sent to the peer',
'# TYPE wireguard_sent_bytes counter',
`${wireguardSentBytes.join('\n')}`,
wireguardSentBytes.join('\n'),
'',
'# HELP wireguard_received_bytes Bytes received from the peer',
'# TYPE wireguard_received_bytes counter',
`${wireguardReceivedBytes.join('\n')}`,
wireguardReceivedBytes.join('\n'),
'',
'# HELP wireguard_latest_handshake_seconds UNIX timestamp seconds of the last handshake',
'# TYPE wireguard_latest_handshake_seconds gauge',
`${wireguardLatestHandshakeSeconds.join('\n')}`,
wireguardLatestHandshakeSeconds.join('\n'),
];
return returnText.join('\n');

4
src/server/utils/Database.ts

@ -16,9 +16,9 @@ const nullObject = new Proxy(
// eslint-disable-next-line import/no-mutable-exports
let provider = nullObject as never as DBServiceType;
connect().then((db) => {
void connect().then((db) => {
provider = db;
WireGuard.Startup();
void WireGuard.Startup();
});
export default provider;

13
src/server/utils/WireGuard.ts

@ -158,10 +158,12 @@ class WireGuard {
WG_DEBUG(`Starting Wireguard Interface ${wgInterface.name}...`);
await this.#saveWireguardConfig(wgInterface);
await wg.down(wgInterface.name).catch(() => {});
await wg.up(wgInterface.name).catch((err) => {
await wg.up(wgInterface.name).catch((err: unknown) => {
if (
err &&
err.message &&
typeof err === 'object' &&
'message' in err &&
typeof err.message === 'string' &&
err.message.includes(`Cannot find device "${wgInterface.name}"`)
) {
throw new Error(
@ -181,13 +183,15 @@ class WireGuard {
}
// TODO: handle as worker_thread
// eslint-disable-next-line @typescript-eslint/require-await
async startCronJob() {
setIntervalImmediately(() => {
this.cronJob().catch((err) => {
this.cronJob().catch((err: unknown) => {
WG_DEBUG('Running Cron Job failed.');
console.error(err);
});
}, 60 * 1000);
return;
}
// Shutdown wireguard
@ -206,7 +210,7 @@ class WireGuard {
let needsSave = false;
// Expires Feature
for (const client of clients) {
if (client.enabled !== true) continue;
if (!client.enabled) continue;
if (
client.expiresAt !== null &&
new Date() > new Date(client.expiresAt)
@ -234,6 +238,7 @@ class WireGuard {
}
}
// eslint-disable-next-line @typescript-eslint/no-deprecated
if (OLD_ENV.PASSWORD || OLD_ENV.PASSWORD_HASH) {
throw new Error(
`

9
src/server/utils/cmd.ts

@ -9,7 +9,7 @@ export function exec(
) {
if (typeof log === 'string') {
CMD_DEBUG(`$ ${log}`);
} else if (log === true) {
} else if (log) {
CMD_DEBUG(`$ ${cmd}`);
}
@ -24,8 +24,11 @@ export function exec(
shell: 'bash',
},
(err, stdout) => {
if (err) return reject(err);
return resolve(String(stdout).trim());
if (err) {
reject(err);
return;
}
resolve(String(stdout).trim());
}
);
});

10
src/server/utils/handler.ts

@ -99,16 +99,16 @@ export const defineSetupEventHandler = <
});
}
const validSetupSteps =
ValidSetupSteps[setup.step as keyof typeof ValidSetupSteps];
if (!validSetupSteps) {
if (!(setup.step in ValidSetupSteps)) {
throw createError({
statusCode: 500,
statusMessage: 'Invalid setup step',
});
}
const validSetupSteps =
ValidSetupSteps[setup.step as keyof typeof ValidSetupSteps];
if (!validSetupSteps.includes(step as never)) {
throw createError({
statusCode: 400,
@ -169,7 +169,7 @@ export const defineMetricsHandler = <
}
}
if (metricsConfig[type] !== true) {
if (!metricsConfig[type]) {
throw createError({
statusCode: 400,
statusMessage: 'Metrics not enabled',

15
src/server/utils/ip.ts

@ -104,17 +104,22 @@ function getPrivateInformation() {
if (internal) {
continue;
}
if (!obj[name]) {
if (!(name in obj)) {
obj[name] = {
ipv4: [],
ipv6: [],
};
}
if (family === 'IPv4') {
obj[name].ipv4.push(address);
} else if (family === 'IPv6') {
obj[name].ipv6.push(address);
switch (family) {
case 'IPv4':
obj[name].ipv4.push(address);
continue;
case 'IPv6':
obj[name].ipv6.push(address);
continue;
}
assertUnreachable(family);
}
}

2
src/server/utils/release.ts

@ -5,7 +5,7 @@ type GithubRelease = {
async function fetchLatestRelease() {
try {
const response = await $fetch<GithubRelease>(
const response = await $fetch<GithubRelease | ''>(
'https://api.github.com/repos/wg-easy/wg-easy/releases/latest',
{ method: 'get', timeout: 5000 }
);

7
src/server/utils/template.ts

@ -4,8 +4,11 @@ import type { InterfaceType } from '#db/repositories/interface/types';
* Replace all {{key}} in the template with the values[key]
*/
export function template(templ: string, values: Record<string, string>) {
return templ.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return values[key] !== undefined ? values[key] : match;
return templ.replace(/\{\{(\w+)\}\}/g, (match, key: string) => {
if (key in values) {
return values[key];
}
return match;
});
}

95
src/server/utils/types.ts

@ -1,6 +1,6 @@
import type { ZodSchema } from 'zod';
import z from 'zod';
import type { H3Event, EventHandlerRequest } from 'h3';
import type { H3Event } from 'h3';
export type ID = number;
@ -63,10 +63,7 @@ export const schemaForType =
return arg;
};
export function validateZod<T>(
schema: ZodSchema<T>,
event: H3Event<EventHandlerRequest>
) {
export function validateZod<T>(schema: ZodSchema<T>, event: H3Event) {
return async (data: unknown) => {
try {
return await schema.parseAsync(data);
@ -79,64 +76,60 @@ export function validateZod<T>(
.map((v) => {
let m = v.message;
if (t) {
let newMessage = null;
if (v.message.startsWith('zod.')) {
switch (v.code) {
case 'too_small':
switch (v.type) {
let newMessage = null;
if (v.message.startsWith('zod.')) {
switch (v.code) {
case 'too_small':
switch (v.type) {
case 'string':
newMessage = t('zod.generic.stringMin', [
t(v.message),
v.minimum,
]);
break;
case 'number':
newMessage = t('zod.generic.numberMin', [
t(v.message),
v.minimum,
]);
break;
}
break;
case 'invalid_type': {
if (v.received === 'null' || v.received === 'undefined') {
newMessage = t('zod.generic.required', [v.path.join('.')]);
} else {
switch (v.expected) {
case 'string':
newMessage = t('zod.generic.stringMin', [
newMessage = t('zod.generic.validString', [
t(v.message),
]);
break;
case 'boolean':
newMessage = t('zod.generic.validBoolean', [
t(v.message),
v.minimum,
]);
break;
case 'number':
newMessage = t('zod.generic.numberMin', [
newMessage = t('zod.generic.validNumber', [
t(v.message),
]);
break;
case 'array':
newMessage = t('zod.generic.validArray', [
t(v.message),
v.minimum,
]);
break;
}
break;
case 'invalid_type': {
if (v.received === 'null' || v.received === 'undefined') {
newMessage = t('zod.generic.required', [
v.path.join('.'),
]);
} else {
switch (v.expected) {
case 'string':
newMessage = t('zod.generic.validString', [
t(v.message),
]);
break;
case 'boolean':
newMessage = t('zod.generic.validBoolean', [
t(v.message),
]);
break;
case 'number':
newMessage = t('zod.generic.validNumber', [
t(v.message),
]);
break;
case 'array':
newMessage = t('zod.generic.validArray', [
t(v.message),
]);
break;
}
}
break;
}
break;
}
}
if (newMessage) {
m = newMessage;
} else {
m = t(v.message);
}
}
if (newMessage) {
m = newMessage;
} else {
m = t(v.message);
}
return m;

2
src/server/utils/wgHelper.ts

@ -10,7 +10,7 @@ export const wg = {
const allowedIps = [
`${client.ipv4Address}/32`,
`${client.ipv6Address}/128`,
...(client.serverAllowedIps ?? []),
...client.serverAllowedIps,
];
const extraLines = [];

2
src/shared/utils/permissions.ts

@ -134,7 +134,7 @@ export function hasPermissionsWithData<Resource extends keyof Permissions>(
) {
let checked = false;
return {
check(data?: Permissions[Resource]['dataType']) {
check(this: void, data?: Permissions[Resource]['dataType']) {
checked = true;
const isAllowed = hasPermissions(user, resource, action, data);

Loading…
Cancel
Save