mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-06 22:37:12 -04:00
Merge a9bf3fe6c7
into 07eea0f484
This commit is contained in:
commit
1f859dc98b
8 changed files with 6760 additions and 8382 deletions
1
components.d.ts
vendored
1
components.d.ts
vendored
|
@ -103,6 +103,7 @@ declare module '@vue/runtime-core' {
|
|||
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
||||
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
||||
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
||||
IpIncludeExclude: typeof import('./src/tools/ip-include-exclude/ip-include-exclude.vue')['default']
|
||||
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
||||
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
|
||||
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
"@vueuse/router": "^10.0.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"change-case": "^4.1.2",
|
||||
"cidr-tools": "^11.0.2",
|
||||
"colord": "^2.9.3",
|
||||
"composerize-ts": "^0.6.2",
|
||||
"country-code-lookup": "^0.1.0",
|
||||
|
@ -70,6 +71,7 @@
|
|||
"highlight.js": "^11.7.0",
|
||||
"iarna-toml-esm": "^3.0.5",
|
||||
"ibantools": "^4.3.3",
|
||||
"ip-matching": "^2.1.2",
|
||||
"js-base64": "^3.7.6",
|
||||
"json5": "^2.2.3",
|
||||
"jwt-decode": "^3.1.2",
|
||||
|
|
14924
pnpm-lock.yaml
generated
14924
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
|||
import { tool as base64FileConverter } from './base64-file-converter';
|
||||
import { tool as base64StringConverter } from './base64-string-converter';
|
||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||
import { tool as ipIncludeExclude } from './ip-include-exclude';
|
||||
import { tool as emailNormalizer } from './email-normalizer';
|
||||
|
||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||
|
@ -164,7 +165,15 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
},
|
||||
{
|
||||
name: 'Network',
|
||||
components: [ipv4SubnetCalculator, ipv4AddressConverter, ipv4RangeExpander, macAddressLookup, macAddressGenerator, ipv6UlaGenerator],
|
||||
components: [
|
||||
ipv4SubnetCalculator,
|
||||
ipv4AddressConverter,
|
||||
ipv4RangeExpander,
|
||||
ipIncludeExclude,
|
||||
macAddressLookup,
|
||||
macAddressGenerator,
|
||||
ipv6UlaGenerator,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Math',
|
||||
|
|
12
src/tools/ip-include-exclude/index.ts
Normal file
12
src/tools/ip-include-exclude/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { UnfoldMoreOutlined } from '@vicons/material';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'IP Subnets Exclude Calculator',
|
||||
path: '/ip-include-exclude',
|
||||
description: 'Substract a disallowed IP Ranges/Mask/CIDR list from an allowed IP Ranges/Mask/CIDR list',
|
||||
keywords: ['ip', 'allowed', 'disallowed', 'include', 'exclude', 'subnet', 'cidr'],
|
||||
component: () => import('./ip-include-exclude.vue'),
|
||||
icon: UnfoldMoreOutlined,
|
||||
createdAt: new Date('2024-08-15'),
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { substractCIDRs } from './ip-include-exclude.service';
|
||||
|
||||
describe('ip-include-exclude', () => {
|
||||
describe('substractCIDRs', () => {
|
||||
it('should return error on invalid values', () => {
|
||||
expect(substractCIDRs({ allowedRanges: '192.168.0.', disallowedRanges: '' })).to.deep.eq({ // NOSONAR
|
||||
allowedCIDRs: [],
|
||||
allowedSubnets: [],
|
||||
disallowedSubnets: [],
|
||||
error: 'Error: Invalid IP (range/subnetwork)',
|
||||
});
|
||||
});
|
||||
it('should return correct substractions and subnets', () => {
|
||||
expect(substractCIDRs({ allowedRanges: '192.168.3.0/24', disallowedRanges: '' })).to.deep.eq({ // NOSONAR
|
||||
allowedCIDRs: ['192.168.3.0/24'], // NOSONAR
|
||||
allowedSubnets: [{ cidr: '192.168.3.0/24', end: '192.168.3.255', start: '192.168.3.0' }], // NOSONAR
|
||||
disallowedSubnets: [],
|
||||
error: '',
|
||||
});
|
||||
expect(substractCIDRs({ allowedRanges: '192.168.2.0/24', disallowedRanges: '192.168.2.1' })).to.deep.eq({ // NOSONAR
|
||||
allowedCIDRs: ['192.168.2.0/32', // NOSONAR
|
||||
'192.168.2.2/31', // NOSONAR
|
||||
'192.168.2.4/30', // NOSONAR
|
||||
'192.168.2.8/29', // NOSONAR
|
||||
'192.168.2.16/28', // NOSONAR
|
||||
'192.168.2.32/27', // NOSONAR
|
||||
'192.168.2.64/26', // NOSONAR
|
||||
'192.168.2.128/25'], // NOSONAR
|
||||
allowedSubnets: [
|
||||
{ cidr: '192.168.2.0/24', end: '192.168.2.255', start: '192.168.2.0' }, // NOSONAR
|
||||
],
|
||||
disallowedSubnets: [
|
||||
{ cidr: '192.168.2.1/32', end: '192.168.2.1', start: '192.168.2.1' }, // NOSONAR
|
||||
],
|
||||
error: '',
|
||||
});
|
||||
expect(substractCIDRs({ allowedRanges: '192.168.12.0/24', disallowedRanges: '192.168.12.1-192.168.12.10, 192.168.12.34' })).to.deep.eq({ // NOSONAR
|
||||
allowedCIDRs: ['192.168.12.0/32', // NOSONAR
|
||||
'192.168.12.11/32', // NOSONAR
|
||||
'192.168.12.12/30', // NOSONAR
|
||||
'192.168.12.16/28', // NOSONAR
|
||||
'192.168.12.32/31', // NOSONAR
|
||||
'192.168.12.35/32', // NOSONAR
|
||||
'192.168.12.36/30', // NOSONAR
|
||||
'192.168.12.40/29', // NOSONAR
|
||||
'192.168.12.48/28', // NOSONAR
|
||||
'192.168.12.64/26', // NOSONAR
|
||||
'192.168.12.128/25'], // NOSONAR
|
||||
allowedSubnets: [{ cidr: '192.168.12.0/24', end: '192.168.12.255', start: '192.168.12.0' }], // NOSONAR
|
||||
disallowedSubnets: [
|
||||
{ cidr: '192.168.12.1/32', end: '192.168.12.1', start: '192.168.12.1' }, // NOSONAR
|
||||
{ cidr: '192.168.12.2/31', end: '192.168.12.3', start: '192.168.12.2' }, // NOSONAR
|
||||
{ cidr: '192.168.12.4/30', end: '192.168.12.7', start: '192.168.12.4' }, // NOSONAR
|
||||
{ cidr: '192.168.12.8/31', end: '192.168.12.9', start: '192.168.12.8' }, // NOSONAR
|
||||
{ cidr: '192.168.12.10/32', end: '192.168.12.10', start: '192.168.12.10' }, // NOSONAR
|
||||
{ cidr: '192.168.12.34/32', end: '192.168.12.34', start: '192.168.12.34' }, // NOSONAR
|
||||
],
|
||||
error: '',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
49
src/tools/ip-include-exclude/ip-include-exclude.service.ts
Normal file
49
src/tools/ip-include-exclude/ip-include-exclude.service.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
import type { IPMask } from 'ip-matching';
|
||||
import { getMatch } from 'ip-matching';
|
||||
import { excludeCidr } from 'cidr-tools';
|
||||
|
||||
function convertToCIDR(mask: IPMask) {
|
||||
const subnet = mask.convertToSubnet();
|
||||
if (!subnet) {
|
||||
return { cidr: mask.toString(), start: '', end: '' };
|
||||
}
|
||||
return {
|
||||
cidr: subnet.toString(),
|
||||
start: subnet.getFirst().toString(),
|
||||
end: subnet.getLast().toString(),
|
||||
};
|
||||
}
|
||||
|
||||
export function substractCIDRs(
|
||||
{ allowedRanges, disallowedRanges }:
|
||||
{
|
||||
allowedRanges: string
|
||||
disallowedRanges: string
|
||||
}) {
|
||||
try {
|
||||
const allowedRangesMatchMasks = allowedRanges.split(/\s*[,;|]+\s*/g) // NOSONAR
|
||||
.filter(range => range)
|
||||
.flatMap(range => getMatch(range)?.convertToMasks() || []);
|
||||
const disallowedRangesMatchMasks = disallowedRanges.split(/\s*[,;|]+\s*/g) // NOSONAR
|
||||
.filter(range => range)
|
||||
.flatMap(range => getMatch(range)?.convertToMasks() || []);
|
||||
|
||||
const allowedSubnets = allowedRangesMatchMasks.map(convertToCIDR);
|
||||
const disallowedSubnets = disallowedRangesMatchMasks.map(convertToCIDR);
|
||||
|
||||
return {
|
||||
error: '',
|
||||
allowedSubnets,
|
||||
disallowedSubnets,
|
||||
allowedCIDRs: excludeCidr(allowedSubnets.map(net => net.cidr), disallowedSubnets.map(net => net.cidr)),
|
||||
};
|
||||
}
|
||||
catch (e: any) {
|
||||
return {
|
||||
error: e.toString(),
|
||||
allowedSubnets: [],
|
||||
disallowedSubnets: [],
|
||||
allowedCIDRs: [],
|
||||
};
|
||||
}
|
||||
}
|
80
src/tools/ip-include-exclude/ip-include-exclude.vue
Normal file
80
src/tools/ip-include-exclude/ip-include-exclude.vue
Normal file
|
@ -0,0 +1,80 @@
|
|||
<script setup lang="ts">
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { substractCIDRs } from './ip-include-exclude.service';
|
||||
import SpanCopyable from '@/components/SpanCopyable.vue';
|
||||
import TextareaCopyable from '@/components/TextareaCopyable.vue';
|
||||
|
||||
const allowedRanges = useStorage('ip-inc-exc:allow', '192.168.0.1/24'); // NOSONAR
|
||||
const disallowedRanges = useStorage('ip-inc-exc:disallow', '192.168.0.6'); // NOSONAR
|
||||
|
||||
const result = computed(() => substractCIDRs({
|
||||
allowedRanges: allowedRanges.value, disallowedRanges: disallowedRanges.value,
|
||||
}));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<c-input-text
|
||||
v-model:value="allowedRanges"
|
||||
label="AllowedIPs (IPv4/6 CIDR/Range/Mask/Wildcard)"
|
||||
placeholder="An IPv4/6 CIDR/Range/Mask/Wildcard..."
|
||||
mb-4
|
||||
/>
|
||||
|
||||
<c-input-text
|
||||
v-model:value="disallowedRanges"
|
||||
label="DisallowedIPs (IPv4/6 CIDR/Range/Mask/Wildcard)"
|
||||
placeholder="An IPv4/6 CIDR/Range/Mask/Wildcard..."
|
||||
mb-4
|
||||
/>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<c-alert v-if="result.error">
|
||||
{{ result.error }}
|
||||
</c-alert>
|
||||
|
||||
<div v-if="!result.error">
|
||||
<n-form-item label="Final AllowedIPs:">
|
||||
<TextareaCopyable :value="result.allowedCIDRs.join(', ')" />
|
||||
</n-form-item>
|
||||
|
||||
<n-divider />
|
||||
|
||||
<c-card title="Allowed Subnets">
|
||||
<n-table>
|
||||
<tbody>
|
||||
<tr v-for="{ cidr, start, end } in result.allowedSubnets" :key="cidr">
|
||||
<td font-bold>
|
||||
<SpanCopyable :value="cidr" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="start" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="end" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</c-card>
|
||||
<c-card title="Disallowed Subnets">
|
||||
<n-table>
|
||||
<tbody>
|
||||
<tr v-for="{ cidr, start, end } in result.disallowedSubnets" :key="cidr">
|
||||
<td font-bold>
|
||||
<SpanCopyable :value="cidr" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="start" />
|
||||
</td>
|
||||
<td>
|
||||
<SpanCopyable :value="end" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</c-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
Loading…
Add table
Add a link
Reference in a new issue