@jjlmoya/utils-tools 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +63 -0
- package/src/category/i18n/en.ts +172 -0
- package/src/category/i18n/es.ts +172 -0
- package/src/category/i18n/fr.ts +172 -0
- package/src/category/index.ts +23 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +90 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +23 -0
- package/src/tests/title_quality.test.ts +56 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/date-diff-calculator/bibliography.astro +14 -0
- package/src/tool/date-diff-calculator/component.astro +370 -0
- package/src/tool/date-diff-calculator/i18n/en.ts +132 -0
- package/src/tool/date-diff-calculator/i18n/es.ts +132 -0
- package/src/tool/date-diff-calculator/i18n/fr.ts +132 -0
- package/src/tool/date-diff-calculator/index.ts +22 -0
- package/src/tool/date-diff-calculator/seo.astro +14 -0
- package/src/tool/date-diff-calculator/ui.ts +17 -0
- package/src/tool/drive-direct-link/bibliography.astro +14 -0
- package/src/tool/drive-direct-link/component.astro +280 -0
- package/src/tool/drive-direct-link/i18n/en.ts +118 -0
- package/src/tool/drive-direct-link/i18n/es.ts +118 -0
- package/src/tool/drive-direct-link/i18n/fr.ts +118 -0
- package/src/tool/drive-direct-link/index.ts +22 -0
- package/src/tool/drive-direct-link/seo.astro +14 -0
- package/src/tool/drive-direct-link/ui.ts +10 -0
- package/src/tool/email-list-cleaner/bibliography.astro +14 -0
- package/src/tool/email-list-cleaner/component.astro +375 -0
- package/src/tool/email-list-cleaner/i18n/en.ts +140 -0
- package/src/tool/email-list-cleaner/i18n/es.ts +140 -0
- package/src/tool/email-list-cleaner/i18n/fr.ts +140 -0
- package/src/tool/email-list-cleaner/index.ts +22 -0
- package/src/tool/email-list-cleaner/seo.astro +14 -0
- package/src/tool/email-list-cleaner/ui.ts +15 -0
- package/src/tool/env-badge-spain/bibliography.astro +14 -0
- package/src/tool/env-badge-spain/component.astro +303 -0
- package/src/tool/env-badge-spain/components/BadgeForm.astro +243 -0
- package/src/tool/env-badge-spain/components/BadgeResult.astro +151 -0
- package/src/tool/env-badge-spain/i18n/en.ts +153 -0
- package/src/tool/env-badge-spain/i18n/es.ts +153 -0
- package/src/tool/env-badge-spain/i18n/fr.ts +153 -0
- package/src/tool/env-badge-spain/index.ts +22 -0
- package/src/tool/env-badge-spain/seo.astro +14 -0
- package/src/tool/env-badge-spain/ui.ts +53 -0
- package/src/tool/morse-beacon/bibliography.astro +14 -0
- package/src/tool/morse-beacon/component.astro +534 -0
- package/src/tool/morse-beacon/i18n/en.ts +157 -0
- package/src/tool/morse-beacon/i18n/es.ts +157 -0
- package/src/tool/morse-beacon/i18n/fr.ts +157 -0
- package/src/tool/morse-beacon/index.ts +22 -0
- package/src/tool/morse-beacon/logic/MorseEngine.ts +124 -0
- package/src/tool/morse-beacon/seo.astro +14 -0
- package/src/tool/morse-beacon/ui.ts +18 -0
- package/src/tool/password-generator/bibliography.astro +14 -0
- package/src/tool/password-generator/component.astro +259 -0
- package/src/tool/password-generator/components/Config.astro +227 -0
- package/src/tool/password-generator/components/Display.astro +147 -0
- package/src/tool/password-generator/components/Strength.astro +70 -0
- package/src/tool/password-generator/i18n/en.ts +166 -0
- package/src/tool/password-generator/i18n/es.ts +166 -0
- package/src/tool/password-generator/i18n/fr.ts +166 -0
- package/src/tool/password-generator/index.ts +22 -0
- package/src/tool/password-generator/seo.astro +14 -0
- package/src/tool/password-generator/ui.ts +16 -0
- package/src/tool/routes/bibliography.astro +14 -0
- package/src/tool/routes/component.astro +543 -0
- package/src/tool/routes/i18n/en.ts +157 -0
- package/src/tool/routes/i18n/es.ts +157 -0
- package/src/tool/routes/i18n/fr.ts +157 -0
- package/src/tool/routes/index.ts +22 -0
- package/src/tool/routes/logic/GeocodingService.ts +60 -0
- package/src/tool/routes/logic/RouteManager.ts +192 -0
- package/src/tool/routes/logic/RouteService.ts +66 -0
- package/src/tool/routes/seo.astro +14 -0
- package/src/tool/routes/ui.ts +16 -0
- package/src/tool/rule-of-three/bibliography.astro +14 -0
- package/src/tool/rule-of-three/component.astro +369 -0
- package/src/tool/rule-of-three/i18n/en.ts +171 -0
- package/src/tool/rule-of-three/i18n/es.ts +171 -0
- package/src/tool/rule-of-three/i18n/fr.ts +171 -0
- package/src/tool/rule-of-three/index.ts +22 -0
- package/src/tool/rule-of-three/seo.astro +14 -0
- package/src/tool/rule-of-three/ui.ts +13 -0
- package/src/tool/seo-content-optimizer/bibliography.astro +14 -0
- package/src/tool/seo-content-optimizer/component.astro +552 -0
- package/src/tool/seo-content-optimizer/i18n/en.ts +136 -0
- package/src/tool/seo-content-optimizer/i18n/es.ts +136 -0
- package/src/tool/seo-content-optimizer/i18n/fr.ts +136 -0
- package/src/tool/seo-content-optimizer/index.ts +22 -0
- package/src/tool/seo-content-optimizer/seo.astro +14 -0
- package/src/tool/seo-content-optimizer/ui.ts +29 -0
- package/src/tool/speed-reader/bibliography.astro +14 -0
- package/src/tool/speed-reader/component.astro +586 -0
- package/src/tool/speed-reader/i18n/en.ts +152 -0
- package/src/tool/speed-reader/i18n/es.ts +152 -0
- package/src/tool/speed-reader/i18n/fr.ts +152 -0
- package/src/tool/speed-reader/index.ts +22 -0
- package/src/tool/speed-reader/logic/RSVPEngine.ts +106 -0
- package/src/tool/speed-reader/seo.astro +14 -0
- package/src/tool/speed-reader/ui.ts +14 -0
- package/src/tool/text-pixel-calculator/bibliography.astro +14 -0
- package/src/tool/text-pixel-calculator/component.astro +315 -0
- package/src/tool/text-pixel-calculator/components/Editor.astro +240 -0
- package/src/tool/text-pixel-calculator/components/Preview.astro +155 -0
- package/src/tool/text-pixel-calculator/components/Stats.astro +87 -0
- package/src/tool/text-pixel-calculator/i18n/en.ts +133 -0
- package/src/tool/text-pixel-calculator/i18n/es.ts +133 -0
- package/src/tool/text-pixel-calculator/i18n/fr.ts +133 -0
- package/src/tool/text-pixel-calculator/index.ts +22 -0
- package/src/tool/text-pixel-calculator/seo.astro +14 -0
- package/src/tool/text-pixel-calculator/ui.ts +15 -0
- package/src/tool/whatsapp-link/bibliography.astro +14 -0
- package/src/tool/whatsapp-link/component.astro +455 -0
- package/src/tool/whatsapp-link/i18n/en.ts +128 -0
- package/src/tool/whatsapp-link/i18n/es.ts +128 -0
- package/src/tool/whatsapp-link/i18n/fr.ts +128 -0
- package/src/tool/whatsapp-link/index.ts +22 -0
- package/src/tool/whatsapp-link/seo.astro +14 -0
- package/src/tool/whatsapp-link/ui.ts +15 -0
- package/src/tools.ts +15 -0
- package/src/types.ts +72 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
2
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
3
|
+
import type { PasswordGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const faqData = [
|
|
6
|
+
{
|
|
7
|
+
question: 'Is it safe to use an online password generator?',
|
|
8
|
+
answer: "Yes, as long as the generator is client-side. Our tool generates passwords locally in your browser using cryptographically secure algorithms. Your password is never sent over the internet or stored on any server.",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
question: "What makes a password 'hacker-proof'?",
|
|
12
|
+
answer: 'The key is entropy (randomness). A mix of uppercase, lowercase, numbers and special symbols combined with a minimum length of 12-16 characters makes a brute-force attack practically impossible with current technology.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Why avoid common words or dates?',
|
|
16
|
+
answer: 'Hackers use dictionary attacks that test millions of words, names and date combinations per second. Purely random passwords follow no linguistic patterns, making them far more secure.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Should I memorise all my passwords?',
|
|
20
|
+
answer: 'Not recommended. The ideal approach is to use a password manager (like Bitwarden, 1Password or your browser built-in) to store these long, random passwords, so you only need to remember one strong master password.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{
|
|
26
|
+
name: 'Set the length',
|
|
27
|
+
text: 'Adjust the slider to choose how many characters your password will have. Current security standards recommend at least 12.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Choose complexity',
|
|
31
|
+
text: 'Check the uppercase, numbers and symbols options according to the requirements of the site where you will use the password.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'Generate the password',
|
|
35
|
+
text: 'Click the generate button. Each click creates a unique, high-entropy combination based on cryptographic algorithms.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Copy with one click',
|
|
39
|
+
text: 'Use the copy button to send the password directly to your clipboard in a secure way.',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
44
|
+
'@context': 'https://schema.org',
|
|
45
|
+
'@type': 'FAQPage',
|
|
46
|
+
mainEntity: faqData.map((item) => ({
|
|
47
|
+
'@type': 'Question',
|
|
48
|
+
name: item.question,
|
|
49
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
50
|
+
})),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const howToSchema: WithContext<HowTo> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'HowTo',
|
|
56
|
+
name: 'How to use the secure password generator',
|
|
57
|
+
step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
61
|
+
'@context': 'https://schema.org',
|
|
62
|
+
'@type': 'SoftwareApplication',
|
|
63
|
+
name: 'Secure Random Password Generator',
|
|
64
|
+
applicationCategory: 'SecurityApplication',
|
|
65
|
+
operatingSystem: 'Web',
|
|
66
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
67
|
+
description: 'Create strong, hack-proof passwords instantly. Free cybersecurity tool to generate random, secure keys.',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const ui: PasswordGeneratorUI = {
|
|
71
|
+
generating: 'Generating...',
|
|
72
|
+
labelSecurity: 'Strength',
|
|
73
|
+
labelLength: 'Length',
|
|
74
|
+
strengthWeak: 'Weak',
|
|
75
|
+
strengthFair: 'Fair',
|
|
76
|
+
strengthGood: 'Good',
|
|
77
|
+
strengthStrong: 'Strong',
|
|
78
|
+
strengthUnbreakable: 'Unbreakable',
|
|
79
|
+
optionUppercase: 'Uppercase',
|
|
80
|
+
optionLowercase: 'Lowercase',
|
|
81
|
+
optionNumbers: 'Numbers',
|
|
82
|
+
optionSymbols: 'Symbols',
|
|
83
|
+
copyTitle: 'Copy',
|
|
84
|
+
regenerateTitle: 'Generate New',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const content: ToolLocaleContent<PasswordGeneratorUI> = {
|
|
88
|
+
slug: 'password-generator',
|
|
89
|
+
title: 'Secure Random Password Generator',
|
|
90
|
+
description: 'Create strong, hack-proof passwords instantly. Free cybersecurity tool to generate random, secure keys.',
|
|
91
|
+
ui,
|
|
92
|
+
faqTitle: 'Frequently Asked Questions',
|
|
93
|
+
faq: faqData,
|
|
94
|
+
howTo: howToData,
|
|
95
|
+
bibliographyTitle: 'References',
|
|
96
|
+
bibliography: [
|
|
97
|
+
{ name: 'Web Cryptography API — MDN Web Docs', url: 'https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API' },
|
|
98
|
+
{ name: 'NIST SP 800-63B: Digital Identity Guidelines', url: 'https://pages.nist.gov/800-63-3/sp800-63b.html' },
|
|
99
|
+
{ name: 'Password — Wikipedia', url: 'https://en.wikipedia.org/wiki/Password' },
|
|
100
|
+
{ name: 'Have I Been Pwned — Check if your password was exposed', url: 'https://haveibeenpwned.com/Passwords' },
|
|
101
|
+
],
|
|
102
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
103
|
+
seo: [
|
|
104
|
+
{
|
|
105
|
+
type: 'title',
|
|
106
|
+
text: 'The Anatomy of an Uncrackable Password',
|
|
107
|
+
level: 2,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'paragraph',
|
|
111
|
+
html: 'Your password is the only barrier between your personal data (banking, medical, photos) and a cybercriminal. Yet the average user still relies on predictable patterns like "123456" or pet names, which can be cracked in <strong>less than a second</strong>.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'comparative',
|
|
115
|
+
columns: 2,
|
|
116
|
+
items: [
|
|
117
|
+
{
|
|
118
|
+
icon: 'mdi:alert-circle',
|
|
119
|
+
title: 'The Danger of Rainbow Tables',
|
|
120
|
+
description: 'Hackers do not guess your password one attempt at a time. They use massive databases (Rainbow Tables) containing millions of pre-computed hashes of common passwords. If your password is in the dictionary or is a famous phrase, it was already compromised before you started using it.',
|
|
121
|
+
points: [],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
icon: 'mdi:flask',
|
|
125
|
+
title: 'The Solution: Pure Entropy',
|
|
126
|
+
description: 'Entropy measures disorder or unpredictability. The higher the entropy (bits), the more time a computer needs to crack it. This tool uses crypto.getRandomValues(), a browser API that generates cryptographically secure random numbers, unlike Math.random() which is predictable.',
|
|
127
|
+
points: [],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'title',
|
|
133
|
+
text: 'Basic Cybersecurity Principles',
|
|
134
|
+
level: 2,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'comparative',
|
|
138
|
+
columns: 3,
|
|
139
|
+
items: [
|
|
140
|
+
{
|
|
141
|
+
icon: 'mdi:ruler',
|
|
142
|
+
title: 'Length over Complexity',
|
|
143
|
+
description: 'A 20-character lowercase-only password is more secure than an 8-character one with rare symbols. Mathematically, each extra character multiplies the difficulty exponentially.',
|
|
144
|
+
points: [],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
icon: 'mdi:eye-off',
|
|
148
|
+
title: 'The Substitution Myth',
|
|
149
|
+
description: 'Replacing "a" with "@" or "e" with "3" (Leetspeak) fools no one. Modern attack dictionaries already include these variations automatically. Avoid using recognisable words.',
|
|
150
|
+
points: [],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
icon: 'mdi:key-chain',
|
|
154
|
+
title: 'Different Site, Different Key',
|
|
155
|
+
description: 'If you use the same password for your email and a forum, and the forum gets hacked, they now have access to your email. Use a Password Manager (like Bitwarden or 1Password) to remember complex passwords for you.',
|
|
156
|
+
points: [],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'tip',
|
|
162
|
+
title: 'Privacy guaranteed',
|
|
163
|
+
html: 'All generation happens <strong>in your browser</strong>. No password is transmitted over the internet or logged on any server. The source code is auditable.',
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
2
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
3
|
+
import type { PasswordGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const faqData = [
|
|
6
|
+
{
|
|
7
|
+
question: '¿Es seguro usar un generador de contraseñas online?',
|
|
8
|
+
answer: "Sí, siempre que el generador sea 'Client-Side'. Nuestra herramienta genera las claves localmente en tu navegador mediante criptografía segura. Tu contraseña nunca se envía a través de internet ni se guarda en ningún servidor.",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
question: "¿Qué hace que una contraseña sea 'hacker-proof'?",
|
|
12
|
+
answer: 'La clave es la entropía (aleatoriedad). Una mezcla de mayúsculas, minúsculas, números y símbolos especiales, combinada con una longitud mínima de 12-16 caracteres, hace que un ataque de fuerza bruta sea prácticamente imposible con la tecnología actual.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: '¿Por qué evitar palabras comunes o fechas?',
|
|
16
|
+
answer: 'Los hackers utilizan ataques de diccionario que prueban millones de palabras, nombres y combinaciones de fechas en segundos. Las claves puramente aleatorias no siguen patrones lingüísticos, lo que las hace mucho más seguras.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: '¿Debo memorizar todas mis contraseñas?',
|
|
20
|
+
answer: 'No es recomendable. Lo ideal es usar un gestor de contraseñas (como Bitwarden, 1Password o el propio del navegador) para guardar estas claves largas y aleatorias, y así solo tener que recordar una clave maestra robusta.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{
|
|
26
|
+
name: 'Definir la longitud',
|
|
27
|
+
text: 'Ajusta el selector para elegir cuántos caracteres tendrá tu clave. El estándar de seguridad actual recomienda al menos 12.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Elegir la complejidad',
|
|
31
|
+
text: 'Marca las opciones de mayúsculas, números y símbolos según los requisitos del sitio donde vayas a usar la contraseña.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'Generar la clave',
|
|
35
|
+
text: 'Pulsa el botón de generar. Cada clic crea una combinación única de alta entropía basada en algoritmos criptográficos.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Copiar con un clic',
|
|
39
|
+
text: 'Utiliza el botón de copiar para llevar la contraseña directamente a tu portapapeles de forma segura.',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
44
|
+
'@context': 'https://schema.org',
|
|
45
|
+
'@type': 'FAQPage',
|
|
46
|
+
mainEntity: faqData.map((item) => ({
|
|
47
|
+
'@type': 'Question',
|
|
48
|
+
name: item.question,
|
|
49
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
50
|
+
})),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const howToSchema: WithContext<HowTo> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'HowTo',
|
|
56
|
+
name: 'Cómo usar el generador de contraseñas seguras',
|
|
57
|
+
step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
61
|
+
'@context': 'https://schema.org',
|
|
62
|
+
'@type': 'SoftwareApplication',
|
|
63
|
+
name: 'Generador de Contraseñas Seguras y Aleatorias',
|
|
64
|
+
applicationCategory: 'SecurityApplication',
|
|
65
|
+
operatingSystem: 'Web',
|
|
66
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
67
|
+
description: 'Crea contraseñas robustas e imposibles de hackear al instante. Herramienta gratuita de ciberseguridad para generar claves aleatorias y seguras.',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const ui: PasswordGeneratorUI = {
|
|
71
|
+
generating: 'Generando...',
|
|
72
|
+
labelSecurity: 'Seguridad',
|
|
73
|
+
labelLength: 'Longitud',
|
|
74
|
+
strengthWeak: 'Débil',
|
|
75
|
+
strengthFair: 'Media',
|
|
76
|
+
strengthGood: 'Buena',
|
|
77
|
+
strengthStrong: 'Excelente',
|
|
78
|
+
strengthUnbreakable: 'Impenetrable',
|
|
79
|
+
optionUppercase: 'Mayúsculas',
|
|
80
|
+
optionLowercase: 'Minúsculas',
|
|
81
|
+
optionNumbers: 'Números',
|
|
82
|
+
optionSymbols: 'Símbolos',
|
|
83
|
+
copyTitle: 'Copiar',
|
|
84
|
+
regenerateTitle: 'Generar Nueva',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const content: ToolLocaleContent<PasswordGeneratorUI> = {
|
|
88
|
+
slug: 'generador-contrasenas',
|
|
89
|
+
title: 'Generador de Contraseñas Seguras y Aleatorias',
|
|
90
|
+
description: 'Crea contraseñas robustas e imposibles de hackear al instante. Herramienta gratuita de ciberseguridad para generar claves aleatorias y seguras.',
|
|
91
|
+
ui,
|
|
92
|
+
faqTitle: 'Preguntas Frecuentes',
|
|
93
|
+
faq: faqData,
|
|
94
|
+
howTo: howToData,
|
|
95
|
+
bibliographyTitle: 'Referencias',
|
|
96
|
+
bibliography: [
|
|
97
|
+
{ name: 'Web Cryptography API — MDN Web Docs', url: 'https://developer.mozilla.org/es/docs/Web/API/Web_Crypto_API' },
|
|
98
|
+
{ name: 'NIST SP 800-63B: Digital Identity Guidelines', url: 'https://pages.nist.gov/800-63-3/sp800-63b.html' },
|
|
99
|
+
{ name: 'Contraseña — Wikipedia', url: 'https://es.wikipedia.org/wiki/Contrase%C3%B1a' },
|
|
100
|
+
{ name: 'Have I Been Pwned — Comprueba si tu contraseña fue expuesta', url: 'https://haveibeenpwned.com/Passwords' },
|
|
101
|
+
],
|
|
102
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
103
|
+
seo: [
|
|
104
|
+
{
|
|
105
|
+
type: 'title',
|
|
106
|
+
text: 'La Anatomía de una Contraseña Indescifrable',
|
|
107
|
+
level: 2,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'paragraph',
|
|
111
|
+
html: 'Tu contraseña es la única barrera entre tus datos personales (bancarios, médicos, fotos) y un ciberdelincuente. Sin embargo, el usuario promedio sigue utilizando patrones predecibles como "123456" o nombres de mascotas, que pueden ser crackeados en <strong>menos de un segundo</strong>.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'comparative',
|
|
115
|
+
columns: 2,
|
|
116
|
+
items: [
|
|
117
|
+
{
|
|
118
|
+
icon: 'mdi:alert-circle',
|
|
119
|
+
title: 'El Peligro de las Tablas Rainbow',
|
|
120
|
+
description: 'Los hackers no "adivinan" tu contraseña probando una por una manualmente. Usan bases de datos gigantescas (Rainbow Tables) con millones de hashes precalculados de contraseñas comunes. Si tu contraseña está en el diccionario o es una frase famosa, ya ha sido hackeada antes de que empieces a usarla.',
|
|
121
|
+
points: [],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
icon: 'mdi:flask',
|
|
125
|
+
title: 'La Solución: Entropía Pura',
|
|
126
|
+
description: 'La entropía mide el desorden o la imprevisibilidad. Cuanto mayor es la entropía (bits), más tiempo necesita un ordenador para crackearla. Esta herramienta utiliza crypto.getRandomValues(), una API del navegador que genera números aleatorios criptográficamente seguros, a diferencia de Math.random() que es predecible.',
|
|
127
|
+
points: [],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'title',
|
|
133
|
+
text: 'Decálogo de Ciberseguridad Básica',
|
|
134
|
+
level: 2,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'comparative',
|
|
138
|
+
columns: 3,
|
|
139
|
+
items: [
|
|
140
|
+
{
|
|
141
|
+
icon: 'mdi:ruler',
|
|
142
|
+
title: 'Longitud antes que Complejidad',
|
|
143
|
+
description: 'Una contraseña de 20 caracteres solo minúsculas es más segura que una de 8 con símbolos raros. Matemáticamente, cada carácter extra multiplica exponencialmente la dificultad.',
|
|
144
|
+
points: [],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
icon: 'mdi:eye-off',
|
|
148
|
+
title: 'El mito de las sustituciones',
|
|
149
|
+
description: 'Cambiar "a" por "@" o "e" por "3" (Leetspeak) no engaña a nadie. Los diccionarios de ataque modernos ya incluyen estas variaciones automáticamente. Evita usar palabras reconocibles.',
|
|
150
|
+
points: [],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
icon: 'mdi:key-chain',
|
|
154
|
+
title: 'Diferente sitio, diferente llave',
|
|
155
|
+
description: 'Si usas la misma contraseña para tu email y para un foro, y hackean el foro, ya tienen acceso a tu email. Usa un Gestor de Contraseñas (como Bitwarden o 1Password) para recordar estas claves complejas.',
|
|
156
|
+
points: [],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'tip',
|
|
162
|
+
title: 'Privacidad garantizada',
|
|
163
|
+
html: 'Toda la generación ocurre <strong>en tu navegador</strong>. Ninguna contraseña se transmite por internet ni se registra en ningún servidor. El código fuente es auditable.',
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
2
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
3
|
+
import type { PasswordGeneratorUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const faqData = [
|
|
6
|
+
{
|
|
7
|
+
question: 'Est-il sûr d\'utiliser un générateur de mots de passe en ligne ?',
|
|
8
|
+
answer: "Oui, à condition que le générateur soit côté client. Notre outil génère les mots de passe localement dans votre navigateur grâce à la cryptographie sécurisée. Votre mot de passe n'est jamais envoyé sur Internet ni stocké sur un serveur.",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
question: 'Qu\'est-ce qui rend un mot de passe "inviolable" ?',
|
|
12
|
+
answer: 'La clé est l\'entropie (le hasard). Un mélange de majuscules, minuscules, chiffres et symboles spéciaux, combiné à une longueur minimale de 12 à 16 caractères, rend une attaque par force brute pratiquement impossible avec la technologie actuelle.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Pourquoi éviter les mots courants ou les dates ?',
|
|
16
|
+
answer: 'Les pirates utilisent des attaques par dictionnaire qui testent des millions de mots, de noms et de combinaisons de dates en quelques secondes. Les mots de passe purement aléatoires ne suivent aucun schéma linguistique, ce qui les rend bien plus sûrs.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Dois-je mémoriser tous mes mots de passe ?',
|
|
20
|
+
answer: 'Ce n\'est pas recommandé. L\'idéal est d\'utiliser un gestionnaire de mots de passe (comme Bitwarden, 1Password ou celui intégré au navigateur) pour stocker ces clés longues et aléatoires, afin de ne devoir mémoriser qu\'un seul mot de passe maître solide.',
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const howToData = [
|
|
25
|
+
{
|
|
26
|
+
name: 'Définir la longueur',
|
|
27
|
+
text: 'Ajustez le curseur pour choisir le nombre de caractères de votre mot de passe. Les normes de sécurité actuelles recommandent au moins 12 caractères.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Choisir la complexité',
|
|
31
|
+
text: 'Cochez les options majuscules, chiffres et symboles selon les exigences du site où vous utiliserez le mot de passe.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'Générer le mot de passe',
|
|
35
|
+
text: 'Cliquez sur le bouton générer. Chaque clic crée une combinaison unique à haute entropie basée sur des algorithmes cryptographiques.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Copier en un clic',
|
|
39
|
+
text: 'Utilisez le bouton copier pour envoyer le mot de passe directement dans votre presse-papiers de manière sécurisée.',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
44
|
+
'@context': 'https://schema.org',
|
|
45
|
+
'@type': 'FAQPage',
|
|
46
|
+
mainEntity: faqData.map((item) => ({
|
|
47
|
+
'@type': 'Question',
|
|
48
|
+
name: item.question,
|
|
49
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
50
|
+
})),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const howToSchema: WithContext<HowTo> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'HowTo',
|
|
56
|
+
name: 'Comment utiliser le générateur de mots de passe sécurisés',
|
|
57
|
+
step: howToData.map((s) => ({ '@type': 'HowToStep', name: s.name, text: s.text })),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
61
|
+
'@context': 'https://schema.org',
|
|
62
|
+
'@type': 'SoftwareApplication',
|
|
63
|
+
name: 'Générateur de mots de passe sécurisés et aléatoires',
|
|
64
|
+
applicationCategory: 'SecurityApplication',
|
|
65
|
+
operatingSystem: 'Web',
|
|
66
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
67
|
+
description: 'Créez des mots de passe robustes et impossibles à pirater instantanément. Outil de cybersécurité gratuit pour générer des clés aléatoires et sécurisées.',
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const ui: PasswordGeneratorUI = {
|
|
71
|
+
generating: 'Génération...',
|
|
72
|
+
labelSecurity: 'Sécurité',
|
|
73
|
+
labelLength: 'Longueur',
|
|
74
|
+
strengthWeak: 'Faible',
|
|
75
|
+
strengthFair: 'Moyen',
|
|
76
|
+
strengthGood: 'Bon',
|
|
77
|
+
strengthStrong: 'Excellent',
|
|
78
|
+
strengthUnbreakable: 'Inviolable',
|
|
79
|
+
optionUppercase: 'Majuscules',
|
|
80
|
+
optionLowercase: 'Minuscules',
|
|
81
|
+
optionNumbers: 'Chiffres',
|
|
82
|
+
optionSymbols: 'Symboles',
|
|
83
|
+
copyTitle: 'Copier',
|
|
84
|
+
regenerateTitle: 'Générer un nouveau',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const content: ToolLocaleContent<PasswordGeneratorUI> = {
|
|
88
|
+
slug: 'generateur-mot-de-passe',
|
|
89
|
+
title: 'Générateur de mots de passe sécurisés et aléatoires',
|
|
90
|
+
description: 'Créez des mots de passe robustes et impossibles à pirater instantanément. Outil de cybersécurité gratuit pour générer des clés aléatoires et sécurisées.',
|
|
91
|
+
ui,
|
|
92
|
+
faqTitle: 'Questions fréquentes',
|
|
93
|
+
faq: faqData,
|
|
94
|
+
howTo: howToData,
|
|
95
|
+
bibliographyTitle: 'Références',
|
|
96
|
+
bibliography: [
|
|
97
|
+
{ name: 'API Web Cryptography — MDN Web Docs', url: 'https://developer.mozilla.org/fr/docs/Web/API/Web_Crypto_API' },
|
|
98
|
+
{ name: 'NIST SP 800-63B : Lignes directrices sur l\'identité numérique', url: 'https://pages.nist.gov/800-63-3/sp800-63b.html' },
|
|
99
|
+
{ name: 'Mot de passe — Wikipédia', url: 'https://fr.wikipedia.org/wiki/Mot_de_passe' },
|
|
100
|
+
{ name: 'Have I Been Pwned — Vérifiez si votre mot de passe a été exposé', url: 'https://haveibeenpwned.com/Passwords' },
|
|
101
|
+
],
|
|
102
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
103
|
+
seo: [
|
|
104
|
+
{
|
|
105
|
+
type: 'title',
|
|
106
|
+
text: 'L\'anatomie d\'un mot de passe indéchiffrable',
|
|
107
|
+
level: 2,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'paragraph',
|
|
111
|
+
html: 'Votre mot de passe est la seule barrière entre vos données personnelles (bancaires, médicales, photos) et un cybercriminel. Pourtant, l\'utilisateur moyen continue d\'utiliser des schémas prévisibles comme "123456" ou des noms d\'animaux, qui peuvent être déchiffrés en <strong>moins d\'une seconde</strong>.',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: 'comparative',
|
|
115
|
+
columns: 2,
|
|
116
|
+
items: [
|
|
117
|
+
{
|
|
118
|
+
icon: 'mdi:alert-circle',
|
|
119
|
+
title: 'Le danger des Rainbow Tables',
|
|
120
|
+
description: 'Les pirates ne devinent pas votre mot de passe en essayant une par une. Ils utilisent d\'immenses bases de données (Rainbow Tables) contenant des millions de hachages pré-calculés de mots de passe courants. Si votre mot de passe figure dans le dictionnaire, il a déjà été compromis avant que vous commenciez à l\'utiliser.',
|
|
121
|
+
points: [],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
icon: 'mdi:flask',
|
|
125
|
+
title: 'La solution : entropie pure',
|
|
126
|
+
description: 'L\'entropie mesure le désordre ou l\'imprévisibilité. Plus l\'entropie (en bits) est élevée, plus un ordinateur a besoin de temps pour la craquer. Cet outil utilise crypto.getRandomValues(), une API du navigateur qui génère des nombres aléatoires cryptographiquement sécurisés, contrairement à Math.random() qui est prévisible.',
|
|
127
|
+
points: [],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'title',
|
|
133
|
+
text: 'Principes fondamentaux de cybersécurité',
|
|
134
|
+
level: 2,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'comparative',
|
|
138
|
+
columns: 3,
|
|
139
|
+
items: [
|
|
140
|
+
{
|
|
141
|
+
icon: 'mdi:ruler',
|
|
142
|
+
title: 'La longueur prime sur la complexité',
|
|
143
|
+
description: 'Un mot de passe de 20 caractères en minuscules est plus sûr qu\'un mot de 8 caractères avec des symboles rares. Mathématiquement, chaque caractère supplémentaire multiplie la difficulté de manière exponentielle.',
|
|
144
|
+
points: [],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
icon: 'mdi:eye-off',
|
|
148
|
+
title: 'Le mythe des substitutions',
|
|
149
|
+
description: 'Remplacer "a" par "@" ou "e" par "3" (Leetspeak) ne trompe personne. Les dictionnaires d\'attaque modernes incluent déjà ces variations automatiquement. Évitez d\'utiliser des mots reconnaissables.',
|
|
150
|
+
points: [],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
icon: 'mdi:key-chain',
|
|
154
|
+
title: 'Site différent, clé différente',
|
|
155
|
+
description: 'Si vous utilisez le même mot de passe pour votre e-mail et un forum, et que le forum est piraté, ils ont accès à votre e-mail. Utilisez un gestionnaire de mots de passe (comme Bitwarden ou 1Password) pour mémoriser ces clés complexes à votre place.',
|
|
156
|
+
points: [],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'tip',
|
|
162
|
+
title: 'Confidentialité garantie',
|
|
163
|
+
html: 'Toute la génération se déroule <strong>dans votre navigateur</strong>. Aucun mot de passe n\'est transmis sur Internet ni enregistré sur un serveur. Le code source est auditable.',
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ToolDefinition, ToolsToolEntry } from '../../types';
|
|
2
|
+
import type { PasswordGeneratorUI } from './ui';
|
|
3
|
+
import PasswordGeneratorComponent from './component.astro';
|
|
4
|
+
import PasswordGeneratorSEO from './seo.astro';
|
|
5
|
+
import PasswordGeneratorBibliography from './bibliography.astro';
|
|
6
|
+
|
|
7
|
+
export const passwordGenerator: ToolsToolEntry<PasswordGeneratorUI> = {
|
|
8
|
+
id: 'password-generator',
|
|
9
|
+
icons: { bg: 'mdi:shield-key', fg: 'mdi:lock-reset' },
|
|
10
|
+
i18n: {
|
|
11
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
12
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
13
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const PASSWORD_GENERATOR_TOOL: ToolDefinition = {
|
|
18
|
+
entry: passwordGenerator,
|
|
19
|
+
Component: PasswordGeneratorComponent,
|
|
20
|
+
SEOComponent: PasswordGeneratorSEO,
|
|
21
|
+
BibliographyComponent: PasswordGeneratorBibliography,
|
|
22
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { passwordGenerator } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await passwordGenerator.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SEORenderer content={{ locale, sections: content.seo }} />}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface PasswordGeneratorUI extends Record<string, string> {
|
|
2
|
+
generating: string;
|
|
3
|
+
labelSecurity: string;
|
|
4
|
+
labelLength: string;
|
|
5
|
+
strengthWeak: string;
|
|
6
|
+
strengthFair: string;
|
|
7
|
+
strengthGood: string;
|
|
8
|
+
strengthStrong: string;
|
|
9
|
+
strengthUnbreakable: string;
|
|
10
|
+
optionUppercase: string;
|
|
11
|
+
optionLowercase: string;
|
|
12
|
+
optionNumbers: string;
|
|
13
|
+
optionSymbols: string;
|
|
14
|
+
copyTitle: string;
|
|
15
|
+
regenerateTitle: string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { routes } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await routes.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SharedBibliography links={content.bibliography} />}
|