This commit is contained in:
Shahrad Elahi 2024-04-24 03:05:01 +03:30
parent 388ffcdbb6
commit 187b747fc2
8 changed files with 45 additions and 68 deletions

View File

@ -45,6 +45,7 @@
"zod": "^3.22.4"
},
"dependencies": {
"@litehex/node-checksum": "^0.2.0",
"@litehex/storage-box": "^0.2.2-canary.0",
"@t3-oss/env-core": "0.7.3",
"bits-ui": "^0.18.0",

View File

@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false
dependencies:
'@litehex/node-checksum':
specifier: ^0.2.0
version: 0.2.0
'@litehex/storage-box':
specifier: ^0.2.2-canary.0
version: 0.2.2-canary.0
@ -624,6 +627,15 @@ packages:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
/@litehex/node-checksum@0.2.0:
resolution: {integrity: sha512-DM8/Hu5SdIZuQSSHDLR21PVFKTHgeChKiA5SFWfmItkHyH5ehnKCJRQCGXdbluLBOa7+tbRLsUybrQ7OLVM08Q==}
hasBin: true
dependencies:
commander: 12.0.0
crc-32: 1.2.2
fast-glob: 3.3.2
dev: false
/@litehex/storage-box@0.2.2-canary.0:
resolution: {integrity: sha512-D1zCp0+aE11M315Q0WL6fnK6vtmav5FIEyCFpJ/SYETx+7QDdlTMrdkXaxbhYNAsopwnyCe4n7RSPwQdpFyU3Q==}
dependencies:
@ -1413,6 +1425,11 @@ packages:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: false
/commander@12.0.0:
resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==}
engines: {node: '>=18'}
dev: false
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@ -1428,6 +1445,12 @@ packages:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
/crc-32@1.2.2:
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
engines: {node: '>=0.8'}
hasBin: true
dev: false
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@ -1686,6 +1709,17 @@ packages:
merge2: 1.4.1
micromatch: 4.0.5
/fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
dependencies:
'@nodelib/fs.stat': 2.0.5
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
micromatch: 4.0.5
dev: false
/fast-redact@3.3.0:
resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==}
engines: {node: '>=6'}

View File

@ -1,16 +1,18 @@
import { createEnv } from '@t3-oss/env-core';
import { z } from 'zod';
import { hex, sha256 } from '$lib/hash';
import { randomUUID } from 'node:crypto';
import { hash, sha256 } from '@litehex/node-checksum';
import 'dotenv/config';
export const env = createEnv({
runtimeEnv: process.env,
emptyStringAsUndefined: true,
server: {
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
STORAGE_PATH: z.string().default('/data/storage.pack'),
AUTH_SECRET: z.string().default(sha256(randomUUID())),
HASHED_PASSWORD: z.string().default(hex('insecure-password')),
HASHED_PASSWORD: z.string().default(hash('hex', 'insecure-password')),
ORIGIN: z.string().optional(),
},
});

View File

@ -1,37 +1,8 @@
import { execa } from 'execa';
import { ip } from 'node-netkit';
import { link } from 'node-netkit/ip';
export default class Network {
public static async dropInterface(inet: string) {
await execa(`ip link delete dev ${inet}`, { shell: true });
}
public static async defaultInterface(): Promise<string> {
const route = await ip.route.defaultRoute();
if (!route) throw new Error('No default route found');
return route.dev;
}
public static async interfaceExists(inet: string): Promise<boolean> {
try {
const { stdout: o } = await execa(`ip link show | grep ${inet}`, { shell: true });
return o.trim() !== '';
} catch (e) {
return false;
}
}
public static async inUsePorts(): Promise<number[]> {
const ports = [];
const { stdout: output } = await execa(
`netstat -tulpn | grep LISTEN | awk '{print $4}' | awk -F ':' '{print $NF}'`,
{ shell: true },
);
for (const line of output.split('\n')) {
const clean = Number(line.trim());
if (!isNaN(clean) && clean !== 0) ports.push(clean);
}
return ports;
const links = await link.list();
return links.some((l) => l.name === inet);
}
}

View File

@ -1,14 +0,0 @@
export const IPV4_REGEX = new RegExp(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/);
/**
* Private IP Address Identifier in Regular Expression
*
* 127. 0.0.0 127.255.255.255 127.0.0.0 /8
* 10. 0.0.0 10.255.255.255 10.0.0.0 /8
* 172. 16.0.0 172. 31.255.255 172.16.0.0 /12
* 192.168.0.0 192.168.255.255 192.168.0.0 /16
*/
export function isPrivateIP(ip: string) {
const ipRegex = /^(127\.)|(10\.)|(172\.1[6-9]\.)|(172\.2[0-9]\.)|(172\.3[0-1]\.)|(192\.168\.)/;
return ipRegex.test(ip);
}

View File

@ -12,6 +12,7 @@ import { fsAccess } from '$lib/fs-extra';
import { client } from '$lib/storage';
import { execa } from 'execa';
import { ip } from 'node-netkit';
import { allocatedPorts } from 'node-netkit/netstat';
export class WGServer {
readonly id: string;
@ -603,7 +604,7 @@ export async function isIPReserved(ip: string): Promise<boolean> {
}
export async function isPortReserved(port: number): Promise<boolean> {
const inUsePorts = [await Network.inUsePorts(), getServers().map((s) => Number(s.listen))].flat();
const inUsePorts = [await allocatedPorts(), getServers().map((s) => Number(s.listen))].flat();
return inUsePorts.includes(port);
}

View File

@ -1,6 +1,6 @@
import { z } from 'zod';
import { isBetween } from '$lib/utils/number';
import { IPV4_REGEX, isPrivateIP } from '$lib/utils/ip';
import { IPV4_REGEX, isPrivateIP } from 'node-netkit/ip';
export const NameSchema = z
.string()

View File

@ -1,18 +0,0 @@
import Network from '$lib/network';
describe('Network', () => {
it('should return default interface', async () => {
const inet = await Network.defaultInterface();
console.log(inet);
});
it('should return in use ports', async () => {
const ports = await Network.inUsePorts();
console.log(ports);
});
it('should check interface exists', async () => {
const exists = await Network.interfaceExists('lo');
console.log(exists);
});
});