Merge 8c0335937f into 63fbd3b45c
				
					
				
			This commit is contained in:
		
						commit
						8dcf86e8be
					
				| @ -60,6 +60,7 @@ | ||||
|     "cronstrue": "^2.26.0", | ||||
|     "crypto-js": "^4.1.1", | ||||
|     "date-fns": "^2.29.3", | ||||
|     "dns-query": "^0.11.2", | ||||
|     "dompurify": "^3.0.6", | ||||
|     "email-normalizer": "^1.0.0", | ||||
|     "emojilib": "^3.0.10", | ||||
|  | ||||
							
								
								
									
										71
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										71
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @ -77,6 +77,9 @@ dependencies: | ||||
|   date-fns: | ||||
|     specifier: ^2.29.3 | ||||
|     version: 2.29.3 | ||||
|   dns-query: | ||||
|     specifier: ^0.11.2 | ||||
|     version: 0.11.2 | ||||
|   dompurify: | ||||
|     specifier: ^3.0.6 | ||||
|     version: 3.0.6 | ||||
| @ -2379,6 +2382,33 @@ packages: | ||||
|     resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@leichtgewicht/base64-codec@1.0.0: | ||||
|     resolution: {integrity: sha512-0cgP4lRBzh3F4tlpTfs7F+PJyBN8j5yUC9KrQFWp/bREswgzZVHE8T1rNyRDWgvALwwpPtnJDQfqWUmxI33Epg==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@leichtgewicht/dns-packet@6.0.3: | ||||
|     resolution: {integrity: sha512-qmVHhFBFiBvPsk/wJ/EdoWHb+tGkzY4haybmDPukhF6w0+8wpEbrHTIRE9LzeUu2P0bAbmrK8WOXt5V5QN6jQg==} | ||||
|     engines: {node: '>=6'} | ||||
|     dependencies: | ||||
|       '@leichtgewicht/ip-codec': 2.0.5 | ||||
|       bytes.js: 0.0.2 | ||||
|       utf8-bytes: 0.0.1 | ||||
|       utf8-codec: 1.0.0 | ||||
|       utf8-length: 0.0.1 | ||||
|       utf8-string-bytes: 1.0.3 | ||||
|     dev: false | ||||
| 
 | ||||
|   /@leichtgewicht/dns-socket@5.0.0: | ||||
|     resolution: {integrity: sha512-Sbrn/OG0HTTPGSkwIDCHy8/tUI6UglIzFsMNjzZn/Na1/i5owSm6rVi9CfKNNjRcUlYEzICELYW6EoZdjwVY2A==} | ||||
|     engines: {node: '>=6'} | ||||
|     dependencies: | ||||
|       '@leichtgewicht/dns-packet': 6.0.3 | ||||
|     dev: false | ||||
| 
 | ||||
|   /@leichtgewicht/ip-codec@2.0.5: | ||||
|     resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@linaria/core@4.2.9: | ||||
|     resolution: {integrity: sha512-ELcu37VNVOT/PU0L6WDIN+aLzNFyJrqoBYT0CucGOCAmODbojUMCv8oJYRbWzA3N34w1t199dN4UFdfRWFG2rg==} | ||||
|     engines: {node: ^12.16.0 || >=13.7.0} | ||||
| @ -2666,9 +2696,11 @@ packages: | ||||
|     dependencies: | ||||
|       '@tabler/icons': 3.20.0 | ||||
|       vue: 3.3.4 | ||||
|     dev: false | ||||
| 
 | ||||
|   /@tabler/icons@3.20.0: | ||||
|     resolution: {integrity: sha512-nXSeUzsCOxX/Of+kdUVQfxL9bG+ck8XCWNf9dGSpE+nhVexRwk/4HiDQDxFDysfT7vfgSut6GXnrZsU5M5dSlA==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /@tiptap/core@2.1.12(@tiptap/pm@2.1.6): | ||||
|     resolution: {integrity: sha512-ZGc3xrBJA9KY8kln5AYTj8y+GDrKxi7u95xIl2eccrqTY5CQeRu6HRNM1yT4mAjuSaG9jmazyjGRlQuhyxCKxQ==} | ||||
| @ -3412,7 +3444,7 @@ packages: | ||||
|     dependencies: | ||||
|       '@unhead/dom': 0.5.1 | ||||
|       '@unhead/schema': 0.5.1 | ||||
|       '@vueuse/shared': 11.0.3(vue@3.3.4) | ||||
|       '@vueuse/shared': 11.1.0(vue@3.3.4) | ||||
|       unhead: 0.5.1 | ||||
|       vue: 3.3.4 | ||||
|     transitivePeerDependencies: | ||||
| @ -4054,8 +4086,8 @@ packages: | ||||
|       - vue | ||||
|     dev: false | ||||
| 
 | ||||
|   /@vueuse/shared@11.0.3(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} | ||||
|   /@vueuse/shared@11.1.0(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==} | ||||
|     dependencies: | ||||
|       vue-demi: 0.14.10(vue@3.3.4) | ||||
|     transitivePeerDependencies: | ||||
| @ -4353,6 +4385,10 @@ packages: | ||||
|       semver: 7.5.4 | ||||
|     dev: true | ||||
| 
 | ||||
|   /bytes.js@0.0.2: | ||||
|     resolution: {integrity: sha512-KrLm4hv5Qs9w6b0U7h1bCdqxrsf+e9QMsfHeyQFzAz94x/5Aqa+FTEUSNBtt5d2VuV3Hfiea3c4ti74RZDDYkg==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /cac@6.7.14: | ||||
|     resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} | ||||
|     engines: {node: '>=8'} | ||||
| @ -4938,6 +4974,17 @@ packages: | ||||
|     resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /dns-query@0.11.2: | ||||
|     resolution: {integrity: sha512-zF8qxQpqCB467o4A63DLpQClo77H642JEKMx0Ra9GFww7Rx0234Fo8NoG0LBoSBZxamWkXfLxhzDG19bTBHvXQ==} | ||||
|     hasBin: true | ||||
|     dependencies: | ||||
|       '@leichtgewicht/base64-codec': 1.0.0 | ||||
|       '@leichtgewicht/dns-packet': 6.0.3 | ||||
|       '@leichtgewicht/dns-socket': 5.0.0 | ||||
|       '@leichtgewicht/ip-codec': 2.0.5 | ||||
|       utf8-codec: 1.0.0 | ||||
|     dev: false | ||||
| 
 | ||||
|   /doctrine@2.1.0: | ||||
|     resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} | ||||
|     engines: {node: '>=0.10.0'} | ||||
| @ -8236,6 +8283,7 @@ packages: | ||||
| 
 | ||||
|   /sortablejs@1.14.0: | ||||
|     resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /source-map-js@1.0.2: | ||||
|     resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} | ||||
| @ -9048,6 +9096,22 @@ packages: | ||||
|       requires-port: 1.0.0 | ||||
|     dev: true | ||||
| 
 | ||||
|   /utf8-bytes@0.0.1: | ||||
|     resolution: {integrity: sha512-GifWmJAx2qAXT+lZLhbkWhBsy7pr6xWHiPWlVToDiELdWgZwt4Ogjf9tlgvKuALzTFR/d+EPQQI9ogJV3957Jg==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /utf8-codec@1.0.0: | ||||
|     resolution: {integrity: sha512-S/QSLezp3qvG4ld5PUfXiH7mCFxLKjSVZRFkB3DOjgwHuJPFDkInAXc/anf7BAbHt/D38ozDzL+QMZ6/7gsI6w==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /utf8-length@0.0.1: | ||||
|     resolution: {integrity: sha512-j/XH2ftofBiobnyApxlN/J6j/ixwT89WEjDcjT66d2i0+GIn9RZfzt8lpEXXE4jUe4NsjBSUq70kS2euQ4nnMw==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /utf8-string-bytes@1.0.3: | ||||
|     resolution: {integrity: sha512-i/I1Omf6lADjVBlwJpQifZOePV15snHny9w04+lc71+3t8PyWuLC/7clyoOSHOBNGXFe2PAGxmTiZ+Z4HWsPyw==} | ||||
|     dev: false | ||||
| 
 | ||||
|   /util-deprecate@1.0.2: | ||||
|     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} | ||||
|     dev: true | ||||
| @ -9369,6 +9433,7 @@ packages: | ||||
|     dependencies: | ||||
|       sortablejs: 1.14.0 | ||||
|       vue: 3.3.4 | ||||
|     dev: false | ||||
| 
 | ||||
|   /vueuc@0.4.51(vue@3.3.4): | ||||
|     resolution: {integrity: sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==} | ||||
|  | ||||
							
								
								
									
										68
									
								
								src/tools/dns-queries/dns-queries.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/tools/dns-queries/dns-queries.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| <script setup lang="ts"> | ||||
| import { combineTXT, query, wellknown } from 'dns-query'; | ||||
| import types from './dns.records.types.json'; | ||||
| 
 | ||||
| const type = ref('A'); | ||||
| const name = ref('google.com'); | ||||
| const answers = ref<string[]>([]); | ||||
| 
 | ||||
| async function queryDNS() { | ||||
|   const endpoints = await wellknown.endpoints('doh'); | ||||
|   try { | ||||
|     const response = await query({ | ||||
|       question: { type: type.value, name: name.value }, | ||||
|     }, { | ||||
|       endpoints, | ||||
|     }); | ||||
|     if (type.value === 'TXT') { | ||||
|       answers.value = (response.answers || []).map(answer => `${answer.name} ${answer.type} ${combineTXT(answer.data as Uint8Array[])} (TTL=${answer.ttl})`); | ||||
|     } | ||||
|     else { | ||||
|       answers.value = (response.answers || []).map(answer => `${answer.name} ${answer.type} ${answer.data} (TTL=${answer.ttl})`); | ||||
|     } | ||||
|   } | ||||
|   catch (error: any) { | ||||
|     answers.value = [error.toString()]; | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <c-input-text | ||||
|       v-model:value="name" | ||||
|       label="Name" | ||||
|       label-position="left" | ||||
|       placeholder="Name to query" | ||||
|       mb-2 | ||||
|     /> | ||||
|     <c-select | ||||
|       v-model:value="type" | ||||
|       searchable | ||||
|       label="DNS record type:" | ||||
|       label-position="left" | ||||
|       :options="Object.values(types).map(kv => ({ value: kv.value, label: `${kv.value}: ${kv.label}` }))" | ||||
|       mb-2 | ||||
|     /> | ||||
| 
 | ||||
|     <div flex justify-center> | ||||
|       <c-button | ||||
|         @click="queryDNS" | ||||
|       > | ||||
|         Send DNS query | ||||
|       </c-button> | ||||
|     </div> | ||||
| 
 | ||||
|     <n-divider /> | ||||
| 
 | ||||
|     <c-card title="Query results"> | ||||
|       <textarea-copyable | ||||
|         v-for="(answer, index) in answers" | ||||
|         :key="index" | ||||
|         :value="answer" | ||||
|         word-wrap | ||||
|         mb-2 | ||||
|       /> | ||||
|     </c-card> | ||||
|   </div> | ||||
| </template> | ||||
							
								
								
									
										49
									
								
								src/tools/dns-queries/dns.records.types.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/tools/dns-queries/dns.records.types.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| [ | ||||
|   { "value": "A", "label": "Address record" }, | ||||
|   { "value": "AAAA", "label": "IPv6 address record" }, | ||||
|   { "value": "AFSDB", "label": "AFS database record" }, | ||||
|   { "value": "APL", "label": "Address Prefix List" }, | ||||
|   { "value": "CAA", "label": "Certification Authority Authorization" }, | ||||
|   { "value": "CDNSKEY", "label": "CDNSKEY" }, | ||||
|   { "value": "CDS", "label": "Child DS" }, | ||||
|   { "value": "CERT", "label": "Certificate record" }, | ||||
|   { "value": "CNAME", "label": "Canonical name record" }, | ||||
|   { "value": "CSYNC", "label": "Child-to-Parent Synchronization" }, | ||||
|   { "value": "DHCID", "label": "DHCP identifier" }, | ||||
|   { "value": "DLV", "label": "DNSSEC Lookaside Validation record" }, | ||||
|   { "value": "DNAME", "label": "Delegation name record" }, | ||||
|   { "value": "DNSKEY", "label": "DNS Key record" }, | ||||
|   { "value": "DS", "label": "Delegation signer" }, | ||||
|   { "value": "EUI48", "label": "MAC address (EUI-48)" }, | ||||
|   { "value": "EUI64", "label": "MAC address (EUI-64)" }, | ||||
|   { "value": "HINFO", "label": "Host Information" }, | ||||
|   { "value": "HIP", "label": "Host Identity Protocol" }, | ||||
|   { "value": "HTTPS", "label": "HTTPS Binding" }, | ||||
|   { "value": "IPSECKEY", "label": "IPsec Key" }, | ||||
|   { "value": "KEY", "label": "Key record" }, | ||||
|   { "value": "KX", "label": "Key Exchanger record" }, | ||||
|   { "value": "LOC", "label": "Location record" }, | ||||
|   { "value": "MX", "label": "Mail exchange record" }, | ||||
|   { "value": "NAPTR", "label": "Naming Authority Pointer" }, | ||||
|   { "value": "NS", "label": "Name server record" }, | ||||
|   { "value": "NSEC", "label": "Next Secure record" }, | ||||
|   { "value": "NSEC3", "label": "Next Secure record version 3" }, | ||||
|   { "value": "NSEC3PARAM", "label": "NSEC3 parameters" }, | ||||
|   { "value": "OPENPGPKEY", "label": "OpenPGP public key record" }, | ||||
|   { "value": "PTR", "label": "PTR Resource Record" }, | ||||
|   { "value": "RP", "label": "Responsible Person" }, | ||||
|   { "value": "RRSIG", "label": "DNSSEC signature" }, | ||||
|   { "value": "SIG", "label": "Signature" }, | ||||
|   { "value": "SMIMEA", "label": "S/MIME cert association" }, | ||||
|   { "value": "SOA", "label": "Start of [a zone of] authority record" }, | ||||
|   { "value": "SRV", "label": "Service locator" }, | ||||
|   { "value": "SSHFP", "label": "SSH Public Key Fingerprint" }, | ||||
|   { "value": "SVCB", "label": "Service Binding" }, | ||||
|   { "value": "TA", "label": "DNSSEC Trust Authorities" }, | ||||
|   { "value": "TKEY", "label": "Transaction Key record" }, | ||||
|   { "value": "TLSA", "label": "TLSA certificate association" }, | ||||
|   { "value": "TSIG", "label": "Transaction Signature" }, | ||||
|   { "value": "TXT", "label": "Text record" }, | ||||
|   { "value": "URI", "label": "Uniform Resource Identifier" }, | ||||
|   { "value": "ZONEMD", "label": "Message Digests for DNS Zones" } | ||||
| ] | ||||
							
								
								
									
										12
									
								
								src/tools/dns-queries/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/tools/dns-queries/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { World } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: 'DNS Queries', | ||||
|   path: '/dns-queries', | ||||
|   description: 'Perform DNS Queries (over HTTPS)', | ||||
|   keywords: ['dns', 'nslookup', 'queries'], | ||||
|   component: () => import('./dns-queries.vue'), | ||||
|   icon: World, | ||||
|   createdAt: new Date('2024-08-15'), | ||||
| }); | ||||
| @ -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 dnsQueries } from './dns-queries'; | ||||
| 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, | ||||
|       macAddressLookup, | ||||
|       macAddressGenerator, | ||||
|       ipv6UlaGenerator, | ||||
|       dnsQueries, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     name: 'Math', | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user