mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
parent
318fb6efb9
commit
a38def7cae
6 changed files with 145 additions and 13 deletions
8
components.d.ts
vendored
8
components.d.ts
vendored
|
@ -73,6 +73,7 @@ declare module '@vue/runtime-core' {
|
||||||
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
||||||
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
||||||
EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
|
EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
|
||||||
|
EmailParser: typeof import('./src/tools/email-parser/email-parser.vue')['default']
|
||||||
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
|
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
|
||||||
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
|
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
|
||||||
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
|
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
|
||||||
|
@ -129,22 +130,19 @@ declare module '@vue/runtime-core' {
|
||||||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||||
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
NCode: typeof import('naive-ui')['NCode']
|
NCode: typeof import('naive-ui')['NCode']
|
||||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||||
NForm: typeof import('naive-ui')['NForm']
|
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
|
||||||
NH1: typeof import('naive-ui')['NH1']
|
NH1: typeof import('naive-ui')['NH1']
|
||||||
NH3: typeof import('naive-ui')['NH3']
|
NH3: typeof import('naive-ui')['NH3']
|
||||||
NIcon: typeof import('naive-ui')['NIcon']
|
NIcon: typeof import('naive-ui')['NIcon']
|
||||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
|
||||||
NLayout: typeof import('naive-ui')['NLayout']
|
NLayout: typeof import('naive-ui')['NLayout']
|
||||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSlider: typeof import('naive-ui')['NSlider']
|
NTable: typeof import('naive-ui')['NTable']
|
||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
|
||||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
"pdf-signature-reader": "^1.4.2",
|
"pdf-signature-reader": "^1.4.2",
|
||||||
"pinia": "^2.0.34",
|
"pinia": "^2.0.34",
|
||||||
"plausible-tracker": "^0.3.8",
|
"plausible-tracker": "^0.3.8",
|
||||||
|
"postal-mime": "^2.2.7",
|
||||||
"qrcode": "^1.5.1",
|
"qrcode": "^1.5.1",
|
||||||
"sql-formatter": "^13.0.0",
|
"sql-formatter": "^13.0.0",
|
||||||
"ua-parser-js": "^1.0.35",
|
"ua-parser-js": "^1.0.35",
|
||||||
|
|
21
pnpm-lock.yaml
generated
21
pnpm-lock.yaml
generated
|
@ -143,6 +143,9 @@ dependencies:
|
||||||
plausible-tracker:
|
plausible-tracker:
|
||||||
specifier: ^0.3.8
|
specifier: ^0.3.8
|
||||||
version: 0.3.8
|
version: 0.3.8
|
||||||
|
postal-mime:
|
||||||
|
specifier: ^2.2.7
|
||||||
|
version: 2.2.7
|
||||||
qrcode:
|
qrcode:
|
||||||
specifier: ^1.5.1
|
specifier: ^1.5.1
|
||||||
version: 1.5.1
|
version: 1.5.1
|
||||||
|
@ -3360,7 +3363,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/dom': 0.5.1
|
'@unhead/dom': 0.5.1
|
||||||
'@unhead/schema': 0.5.1
|
'@unhead/schema': 0.5.1
|
||||||
'@vueuse/shared': 10.11.1(vue@3.3.4)
|
'@vueuse/shared': 11.0.3(vue@3.3.4)
|
||||||
unhead: 0.5.1
|
unhead: 0.5.1
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -3993,19 +3996,19 @@ packages:
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared@10.11.1(vue@3.3.4):
|
/@vueuse/shared@10.3.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
|
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.14.10(vue@3.3.4)
|
vue-demi: 0.14.5(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared@10.3.0(vue@3.3.4):
|
/@vueuse/shared@11.0.3(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.14.5(vue@3.3.4)
|
vue-demi: 0.14.10(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
@ -7448,6 +7451,10 @@ packages:
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/postal-mime@2.2.7:
|
||||||
|
resolution: {integrity: sha512-13BykdDhBz5QCJ3tVWKW6eTX3ghLqlxm6CxS91AanUptB53+csbIyDW4KdP+IzYZHF+xZ2CkTiBTK+k0/3vR8w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-selector-parser@6.0.13:
|
/postcss-selector-parser@6.0.13:
|
||||||
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
|
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
105
src/tools/email-parser/email-parser.vue
Normal file
105
src/tools/email-parser/email-parser.vue
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import PostalMime from 'postal-mime';
|
||||||
|
|
||||||
|
const emailContent = ref('');
|
||||||
|
|
||||||
|
const parsedEmail = computedAsync(async () => {
|
||||||
|
const emailContentValue = emailContent.value;
|
||||||
|
try {
|
||||||
|
return await PostalMime.parse(emailContentValue);
|
||||||
|
}
|
||||||
|
catch (e: any) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function downloadFile(data: Uint8Array, fileName: string, fileType: string) {
|
||||||
|
const blob = new Blob([data], { type: fileType || 'application/octet-stream' });
|
||||||
|
const downloadUrl = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = downloadUrl;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(downloadUrl);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="max-width: 600px;">
|
||||||
|
<c-card title="Input" mb-2>
|
||||||
|
<c-input-text
|
||||||
|
v-model:value="emailContent"
|
||||||
|
label="Email Content"
|
||||||
|
multiline
|
||||||
|
placeholder="Put your eml/email content here..."
|
||||||
|
rows="15"
|
||||||
|
mb-2
|
||||||
|
/>
|
||||||
|
</c-card>
|
||||||
|
|
||||||
|
<c-card v-if="parsedEmail && emailContent" title="Output">
|
||||||
|
<input-copyable v-if="parsedEmail.date" label="Date" :value="parsedEmail.date" />
|
||||||
|
<input-copyable v-if="parsedEmail.from?.name" label="From (name)" :value="parsedEmail.from?.name" />
|
||||||
|
<input-copyable v-if="parsedEmail.from" label="From (address)" :value="parsedEmail.from?.address || parsedEmail.from" />
|
||||||
|
<input-copyable v-if="parsedEmail.to" label="To" :value="JSON.stringify(parsedEmail.to)" />
|
||||||
|
<input-copyable v-if="parsedEmail.cc" label="Cc" :value="JSON.stringify(parsedEmail.cc)" />
|
||||||
|
<input-copyable v-if="parsedEmail.bcc?.name" label="Bcc" :value="JSON.stringify(parsedEmail.bcc)" />
|
||||||
|
<input-copyable v-if="parsedEmail.replyTo" label="Reply-To" :value="JSON.stringify(parsedEmail.replyTo)" />
|
||||||
|
<input-copyable v-if="parsedEmail.subject" label="Subject" :value="parsedEmail.subject" />
|
||||||
|
<c-card v-if="parsedEmail.text" title="Plain Content" mb-2>
|
||||||
|
<details>
|
||||||
|
<summary>See content</summary>
|
||||||
|
<textarea-copyable :value="parsedEmail.text" />
|
||||||
|
</details>
|
||||||
|
</c-card>
|
||||||
|
<c-card v-if="parsedEmail.html" title="Html Content" mb-2>
|
||||||
|
<details>
|
||||||
|
<summary>See content</summary>
|
||||||
|
<textarea-copyable :value="parsedEmail.html" />
|
||||||
|
</details>
|
||||||
|
</c-card>
|
||||||
|
<c-card v-if="parsedEmail?.attachments?.length" title="Attachments" mb-2>
|
||||||
|
<n-table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Attachment</th><th />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(h, index) in parsedEmail.attachments || []"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<td>
|
||||||
|
{{ `${h.filename || h.contentId || 'noname'} (${h.mimeType}) / ${h.disposition}` }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<c-button @click="downloadFile(h.content, h.filename || h.contentId || 'noname', h.mimeType)">
|
||||||
|
Download
|
||||||
|
</c-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</n-table>
|
||||||
|
</c-card>
|
||||||
|
|
||||||
|
<input-copyable v-if="parsedEmail.messageId" label="Message Id" :value="parsedEmail.messageId" />
|
||||||
|
<input-copyable v-if="parsedEmail.inReplyTo" label="In Reply To" :value="parsedEmail.inReplyTo" />
|
||||||
|
<input-copyable v-if="parsedEmail.references" label="References" :value="parsedEmail.references" />
|
||||||
|
<input-copyable v-if="parsedEmail.deliveredTo" label="Delivered To" :value="parsedEmail.deliveredTo" />
|
||||||
|
<input-copyable v-if="parsedEmail.returnPath" label="Return Path" :value="parsedEmail.returnPath" />
|
||||||
|
<input-copyable v-if="parsedEmail.sender?.name" label="Sender (name)" :value="parsedEmail.sender?.name" />
|
||||||
|
<input-copyable v-if="parsedEmail.sender" label="Sender (address)" :value="parsedEmail.sender?.address || parsedEmail.sender" />
|
||||||
|
|
||||||
|
<c-card title="All Headers" mt-2>
|
||||||
|
<input-copyable
|
||||||
|
v-for="(h, index) in parsedEmail.headers || []"
|
||||||
|
:key="index"
|
||||||
|
:label="h.key"
|
||||||
|
:value="h.value"
|
||||||
|
/>
|
||||||
|
</c-card>
|
||||||
|
</c-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
12
src/tools/email-parser/index.ts
Normal file
12
src/tools/email-parser/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Mail } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'Email Parser',
|
||||||
|
path: '/email-parser',
|
||||||
|
description: 'Parse and extract information from raw Email content',
|
||||||
|
keywords: ['email', 'parser', 'header', 'rfc2822', 'rfc5322', 'rfc822'],
|
||||||
|
component: () => import('./email-parser.vue'),
|
||||||
|
icon: Mail,
|
||||||
|
createdAt: new Date('2024-08-15'),
|
||||||
|
});
|
|
@ -2,6 +2,7 @@ import { tool as base64FileConverter } from './base64-file-converter';
|
||||||
import { tool as base64StringConverter } from './base64-string-converter';
|
import { tool as base64StringConverter } from './base64-string-converter';
|
||||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||||
import { tool as emailNormalizer } from './email-normalizer';
|
import { tool as emailNormalizer } from './email-normalizer';
|
||||||
|
import { tool as emailParser } from './email-parser';
|
||||||
|
|
||||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||||
|
|
||||||
|
@ -158,7 +159,15 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Network',
|
name: 'Network',
|
||||||
components: [ipv4SubnetCalculator, ipv4AddressConverter, ipv4RangeExpander, macAddressLookup, macAddressGenerator, ipv6UlaGenerator],
|
components: [
|
||||||
|
ipv4SubnetCalculator,
|
||||||
|
ipv4AddressConverter,
|
||||||
|
ipv4RangeExpander,
|
||||||
|
macAddressLookup,
|
||||||
|
macAddressGenerator,
|
||||||
|
ipv6UlaGenerator,
|
||||||
|
emailParser,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Math',
|
name: 'Math',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue