@jjlmoya/utils-developer 1.16.0 → 1.18.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.
Files changed (63) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +7 -1
  4. package/src/index.ts +4 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/calculadoraTiempoDatos/data-time-calculator-web-speed-impact.css +498 -499
  8. package/src/tool/jwtDecoder/bibliography.astro +14 -0
  9. package/src/tool/jwtDecoder/bibliography.ts +12 -0
  10. package/src/tool/jwtDecoder/component.astro +209 -0
  11. package/src/tool/jwtDecoder/entry.ts +30 -0
  12. package/src/tool/jwtDecoder/i18n/de.ts +248 -0
  13. package/src/tool/jwtDecoder/i18n/en.ts +247 -0
  14. package/src/tool/jwtDecoder/i18n/es.ts +248 -0
  15. package/src/tool/jwtDecoder/i18n/fr.ts +248 -0
  16. package/src/tool/jwtDecoder/i18n/id.ts +248 -0
  17. package/src/tool/jwtDecoder/i18n/it.ts +248 -0
  18. package/src/tool/jwtDecoder/i18n/ja.ts +248 -0
  19. package/src/tool/jwtDecoder/i18n/ko.ts +248 -0
  20. package/src/tool/jwtDecoder/i18n/nl.ts +247 -0
  21. package/src/tool/jwtDecoder/i18n/pl.ts +247 -0
  22. package/src/tool/jwtDecoder/i18n/pt.ts +247 -0
  23. package/src/tool/jwtDecoder/i18n/ru.ts +248 -0
  24. package/src/tool/jwtDecoder/i18n/sv.ts +248 -0
  25. package/src/tool/jwtDecoder/i18n/tr.ts +248 -0
  26. package/src/tool/jwtDecoder/i18n/zh.ts +248 -0
  27. package/src/tool/jwtDecoder/index.ts +11 -0
  28. package/src/tool/jwtDecoder/jwt-decoder-parser-and-claims-inspector.css +358 -0
  29. package/src/tool/jwtDecoder/logic.ts +96 -0
  30. package/src/tool/jwtDecoder/seo.astro +15 -0
  31. package/src/tool/jwtDecoder/ui.ts +38 -0
  32. package/src/tool/serpPixelSimulator/bibliography.astro +11 -4
  33. package/src/tool/serpPixelSimulator/index.ts +0 -4
  34. package/src/tool/serpPixelSimulator/seo.astro +8 -5
  35. package/src/tool/visualCssGridFlexboxGenerator/bibliography.astro +14 -0
  36. package/src/tool/visualCssGridFlexboxGenerator/bibliography.ts +20 -0
  37. package/src/tool/visualCssGridFlexboxGenerator/canvas.ts +103 -0
  38. package/src/tool/visualCssGridFlexboxGenerator/component.astro +218 -0
  39. package/src/tool/visualCssGridFlexboxGenerator/entry.ts +30 -0
  40. package/src/tool/visualCssGridFlexboxGenerator/i18n/de.ts +110 -0
  41. package/src/tool/visualCssGridFlexboxGenerator/i18n/en.ts +256 -0
  42. package/src/tool/visualCssGridFlexboxGenerator/i18n/es.ts +110 -0
  43. package/src/tool/visualCssGridFlexboxGenerator/i18n/fr.ts +110 -0
  44. package/src/tool/visualCssGridFlexboxGenerator/i18n/id.ts +110 -0
  45. package/src/tool/visualCssGridFlexboxGenerator/i18n/it.ts +110 -0
  46. package/src/tool/visualCssGridFlexboxGenerator/i18n/ja.ts +110 -0
  47. package/src/tool/visualCssGridFlexboxGenerator/i18n/ko.ts +110 -0
  48. package/src/tool/visualCssGridFlexboxGenerator/i18n/nl.ts +110 -0
  49. package/src/tool/visualCssGridFlexboxGenerator/i18n/pl.ts +110 -0
  50. package/src/tool/visualCssGridFlexboxGenerator/i18n/pt.ts +110 -0
  51. package/src/tool/visualCssGridFlexboxGenerator/i18n/ru.ts +110 -0
  52. package/src/tool/visualCssGridFlexboxGenerator/i18n/sv.ts +110 -0
  53. package/src/tool/visualCssGridFlexboxGenerator/i18n/tr.ts +110 -0
  54. package/src/tool/visualCssGridFlexboxGenerator/i18n/zh.ts +110 -0
  55. package/src/tool/visualCssGridFlexboxGenerator/index.ts +11 -0
  56. package/src/tool/visualCssGridFlexboxGenerator/interactions.ts +45 -0
  57. package/src/tool/visualCssGridFlexboxGenerator/logic.ts +49 -0
  58. package/src/tool/visualCssGridFlexboxGenerator/presets.ts +63 -0
  59. package/src/tool/visualCssGridFlexboxGenerator/seo.astro +15 -0
  60. package/src/tool/visualCssGridFlexboxGenerator/ui.ts +58 -0
  61. package/src/tool/visualCssGridFlexboxGenerator/visual-css-grid-flexbox-generator.css +816 -0
  62. package/src/tool/visualCssGridFlexboxGenerator/workspace.ts +192 -0
  63. package/src/tools.ts +3 -1
@@ -0,0 +1,248 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { JwtDecoderUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
5
+
6
+ const slug = 'decodificatore-jwt-parser-e-ispettore-di-claims';
7
+ const title = 'Decodificatore JWT, Parser e Ispettore di Claims';
8
+ const description = 'Incolla un JSON Web Token, decodifica header e payload all\'istante, ispeziona i claims registrati, individua i token scaduti e copia JSON pulito per il debug dei flussi di autenticazione.';
9
+
10
+ const howTo = [
11
+ {
12
+ name: 'Incolla il JWT',
13
+ text: 'Copia un token da un header Authorization, cookie, voce di log o provider di identità e incollalo nel campo di input.',
14
+ },
15
+ {
16
+ name: 'Leggi header e payload decodificati',
17
+ text: 'Lo strumento divide il token in header, payload e firma, quindi visualizza i segmenti JSON in pannelli separati per un\'ispezione rapida.',
18
+ },
19
+ {
20
+ name: 'Controlla i claims importanti',
21
+ text: 'Esamina algoritmo, emittente, audience, soggetto, data di emissione, data di inizio validità e data di scadenza senza convertire manualmente i timestamp Unix.',
22
+ },
23
+ {
24
+ name: 'Copia i dati che ti servono',
25
+ text: 'Copia una sezione decodificata o l\'intero output decodificato quando devi condividere un\'istantanea di debug pulita con il tuo team.',
26
+ },
27
+ ];
28
+
29
+ const faq = [
30
+ {
31
+ question: 'Decodificare un JWT dimostra che il token è valido?',
32
+ answer: 'No. La decodifica rivela solo l\'header e il payload codificati in base64url. Un token è affidabile solo dopo che la firma, l\'emittente, l\'audience, la scadenza e i claims correlati sono stati convalidati dall\'applicazione o dal provider di identità.',
33
+ },
34
+ {
35
+ question: 'Posso usare questo decodificatore JWT per access token e ID token?',
36
+ answer: 'Sì. Il decodificatore è utile per ispezionare access token OAuth, ID token OpenID Connect, token di sessione e token da servizio a servizio, purché utilizzino il formato JWT standard in tre parti.',
37
+ },
38
+ {
39
+ question: 'Perché il pannello della firma non verifica il token?',
40
+ answer: 'La verifica JWT richiede il segreto corretto, la chiave pubblica o la configurazione JWKS. Questo strumento si concentra intenzionalmente sulla decodifica e sull\'ispezione, così che gli sviluppatori possano vedere il contenuto del token senza fingere che una stringa di firma visibile sia una prova di validità.',
41
+ },
42
+ {
43
+ question: 'Cosa dovrei controllare per primo quando faccio debug di un JWT?',
44
+ answer: 'Inizia con exp, nbf, iss, aud e alg. La maggior parte dei problemi reali in produzione deriva da token scaduti, sfasamento dell\'orologio, valori di audience errati, URL dell\'emittente inaspettati o ipotesi di algoritmo non sicure.',
45
+ },
46
+ ];
47
+
48
+ const ui: JwtDecoderUI = {
49
+ tokenLabel: 'Token JWT',
50
+ tokenPlaceholder: 'Incolla un JWT qui: header.payload.firma',
51
+ sampleButton: 'Carica esempio',
52
+ clearButton: 'Cancella',
53
+ statusWaiting: 'Incolla un token per decodificare il suo header JSON, payload e claims.',
54
+ statusValid: 'JWT decodificato con successo.',
55
+ statusInvalid: 'Questo non sembra un JWT valido in tre parti.',
56
+ statusExpired: 'JWT decodificato, ma il claim exp è già scaduto.',
57
+ statusUnsigned: 'JWT decodificato, ma non è firmato o utilizza l\'algoritmo none.',
58
+ headerTitle: 'Header',
59
+ payloadTitle: 'Payload',
60
+ signatureTitle: 'Firma',
61
+ claimsTitle: 'Claims registrati',
62
+ copyHeader: 'Copia header decodificato',
63
+ copyPayload: 'Copia payload decodificato',
64
+ copySignature: 'Copia firma',
65
+ copyAll: 'Copia tutto',
66
+ copiedLabel: 'Copiato',
67
+ invalidTokenTitle: 'JWT non valido',
68
+ invalidTokenBody: 'Verifica che il token abbia tre segmenti base64url separati da punti.',
69
+ invalidSegmentError: 'Verifica che il token abbia tre segmenti base64url separati da punti.',
70
+ invalidDecodeError: 'L\'header o il payload non hanno potuto essere decodificati come JSON valido.',
71
+ emptyJson: '{}',
72
+ signaturePresent: 'Il segmento della firma è presente; verificalo nel tuo livello di autenticazione con la chiave corretta.',
73
+ signatureMissing: 'Nessun segmento di firma',
74
+ algorithmLabel: 'Algoritmo',
75
+ typeLabel: 'Tipo',
76
+ issuerLabel: 'Emittente',
77
+ subjectLabel: 'Soggetto',
78
+ audienceLabel: 'Audience',
79
+ issuedAtLabel: 'Emesso il',
80
+ notBeforeLabel: 'Valido dal',
81
+ expiresAtLabel: 'Scade il',
82
+ claimMissing: 'Non presente',
83
+ privacyNote: 'La decodifica viene eseguita nella sessione del browser. Non incollare segreti di produzione in nessuno strumento, a meno che la tua politica di sicurezza non lo consenta.',
84
+ sampleToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnYW1lYm9iLXVzZXItNDIiLCJuYW1lIjoiR2FtZUJvYiBEZXZlbG9wZXIiLCJpc3MiOiJodHRwczovL3d3dy5nYW1lYm9iLmRldiIsImF1ZCI6ImRldmVsb3Blci10b29scyIsImlhdCI6MTcxNzIwMDAwMCwibmJmIjoxNzE3MjAwMDAwLCJleHAiOjE4OTM0NTYwMDAsInJvbGUiOiJhZG1pbiJ9.demo-signature',
85
+ };
86
+
87
+ const faqSchema: WithContext<FAQPage> = {
88
+ '@context': 'https://schema.org',
89
+ '@type': 'FAQPage',
90
+ mainEntity: faq.map((item) => ({
91
+ '@type': 'Question',
92
+ name: item.question,
93
+ acceptedAnswer: {
94
+ '@type': 'Answer',
95
+ text: item.answer,
96
+ },
97
+ })),
98
+ };
99
+
100
+ const howToSchema: WithContext<HowTo> = {
101
+ '@context': 'https://schema.org',
102
+ '@type': 'HowTo',
103
+ name: title,
104
+ description,
105
+ step: howTo.map((step, index) => ({
106
+ '@type': 'HowToStep',
107
+ position: index + 1,
108
+ name: step.name,
109
+ text: step.text,
110
+ })),
111
+ };
112
+
113
+ const appSchema: WithContext<SoftwareApplication> = {
114
+ '@context': 'https://schema.org',
115
+ '@type': 'SoftwareApplication',
116
+ name: title,
117
+ description,
118
+ applicationCategory: 'DeveloperApplication',
119
+ operatingSystem: 'Any',
120
+ offers: {
121
+ '@type': 'Offer',
122
+ price: '0',
123
+ priceCurrency: 'EUR',
124
+ },
125
+ inLanguage: 'it',
126
+ };
127
+
128
+ export const content: ToolLocaleContent<JwtDecoderUI> = {
129
+ slug,
130
+ title,
131
+ description,
132
+ ui,
133
+ faqTitle: 'Domande frequenti sul decodificatore JWT',
134
+ faq,
135
+ bibliographyTitle: 'Specifiche JWT e riferimenti di sicurezza',
136
+ bibliography,
137
+ howTo,
138
+ schemas: [appSchema, faqSchema, howToSchema],
139
+ seo: [
140
+ {
141
+ type: 'title',
142
+ text: 'Decodifica i JWT senza perdere il contesto di sicurezza',
143
+ level: 2,
144
+ },
145
+ {
146
+ type: 'paragraph',
147
+ html: 'Un JSON Web Token sembra compatto, ma spesso contiene il dettaglio esatto che spiega un errore di autenticazione: l\'algoritmo di firma, l\'emittente, l\'audience, il soggetto, la data di emissione, la data di inizio validità, la scadenza e i claims di autorizzazione specifici dell\'applicazione. Questo <strong>decodificatore JWT, parser e ispettore di claims</strong> trasforma i tre segmenti del token in JSON leggibile per aiutarti a fare debug dei flussi di autenticazione più velocemente.',
148
+ },
149
+ {
150
+ type: 'diagnostic',
151
+ variant: 'warning',
152
+ title: 'Decodificato non significa affidabile',
153
+ html: 'Chiunque può decodificare un JWT in base64url. La fiducia inizia solo dopo che la tua applicazione ha verificato la firma con il segreto, la chiave pubblica o il JWKS corretti, e poi ha convalidato emittente, audience, scadenza ed eventuali claims specifici del dominio. Usa questo strumento per ispezionare i dati, non per accettare un token come autentico.',
154
+ },
155
+ {
156
+ type: 'title',
157
+ text: 'Cosa ti dice ogni segmento JWT',
158
+ level: 3,
159
+ },
160
+ {
161
+ type: 'table',
162
+ headers: ['Segmento', 'Contenuto tipico', 'Valore di debug'],
163
+ rows: [
164
+ ['Header', 'Algoritmo, tipo di token e ID chiave opzionale', 'Mostra se il token prevede HS256, RS256, ES256 o un\'altra strategia di verifica.'],
165
+ ['Payload', 'Claims registrati e claims applicativi', 'Rivela identità, tenant, scope, ruoli, scadenza e disallineamenti di audience.'],
166
+ ['Firma', 'Byte della firma crittografica codificati come base64url', 'Conferma che esiste un segmento di firma, ma deve essere verificato con la chiave corretta altrove.'],
167
+ ],
168
+ },
169
+ {
170
+ type: 'title',
171
+ text: 'Claims che di solito spiegano gli errori di autenticazione',
172
+ level: 3,
173
+ },
174
+ {
175
+ type: 'list',
176
+ items: [
177
+ '<strong>exp:</strong> se il token è scaduto, la logica di refresh o le impostazioni dell\'orologio potrebbero essere errate.',
178
+ '<strong>nbf:</strong> se il token non è ancora attivo, gli orologi del server e del provider di identità potrebbero non essere sincronizzati.',
179
+ '<strong>iss:</strong> se l\'URL dell\'emittente differisce dalla configurazione, il token potrebbe provenire dal tenant o dall\'ambiente sbagliato.',
180
+ '<strong>aud:</strong> se l\'audience non corrisponde all\'identificatore dell\'API, il token è stato emesso per un\'altra risorsa.',
181
+ '<strong>alg:</strong> se l\'algoritmo è inaspettato, il tuo verificatore potrebbe rifiutare il token o esporre un pericoloso errore di configurazione.',
182
+ ],
183
+ },
184
+ {
185
+ type: 'title',
186
+ text: 'Casi d\'uso di un parser JWT durante lo sviluppo',
187
+ level: 3,
188
+ },
189
+ {
190
+ type: 'comparative',
191
+ columns: 3,
192
+ items: [
193
+ {
194
+ title: 'Debug frontend',
195
+ description: 'Ispeziona gli ID token e gli access token ricevuti dopo il login per confermare scope, ruoli e claims del profilo.',
196
+ icon: 'mdi:monitor-dashboard',
197
+ points: ['Controlla i claims del profilo', 'Conferma scope e ruoli', 'Confronta gli ambienti di login'],
198
+ },
199
+ {
200
+ title: 'QA API backend',
201
+ description: 'Confronta i valori attesi di emittente e audience con il token effettivamente inviato in un header Authorization.',
202
+ icon: 'mdi:api',
203
+ highlight: true,
204
+ points: ['Convalida la forma dell\'audience', 'Individua disallineamenti dell\'emittente', 'Ispeziona i bearer token'],
205
+ },
206
+ {
207
+ title: 'Configurazione del provider di identità',
208
+ description: 'Verifica se i claims di Auth0, Azure AD, Cognito, Keycloak o di un provider personalizzato sono strutturati come la tua app si aspetta.',
209
+ icon: 'mdi:account-key',
210
+ points: ['Esamina i dati del tenant', 'Controlla i claims personalizzati', 'Confronta i mapping del provider'],
211
+ },
212
+ ],
213
+ },
214
+ {
215
+ type: 'title',
216
+ text: 'Errori JWT comuni che questo ispettore rende evidenti',
217
+ level: 3,
218
+ },
219
+ {
220
+ type: 'proscons',
221
+ title: 'Verifiche rapide contro decisioni di fiducia',
222
+ items: [
223
+ {
224
+ pro: 'Vedi immediatamente i token malformati.',
225
+ con: 'Non può conoscere l\'audience o l\'emittente che ti aspetti.',
226
+ },
227
+ {
228
+ pro: 'Converti i claims timestamp Unix in date leggibili.',
229
+ con: 'Non può verificare una firma senza il materiale della chiave reale.',
230
+ },
231
+ {
232
+ pro: 'Individua valori mancanti di emittente, audience, soggetto o tipo.',
233
+ con: 'Non può dimostrare che scope e ruoli sono sicuri per la tua applicazione.',
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ type: 'summary',
239
+ title: 'Flusso di lavoro consigliato',
240
+ items: [
241
+ 'Decodifica il token per capire cosa ha effettivamente ricevuto il client o l\'API.',
242
+ 'Controlla exp, nbf, iss, aud, sub e alg prima di inseguire la logica applicativa.',
243
+ 'Verifica le firme e le decisioni di fiducia solo nel tuo livello di autenticazione.',
244
+ 'Evita di condividere JWT di produzione sensibili in ticket, log o screenshot.',
245
+ ],
246
+ },
247
+ ],
248
+ };
@@ -0,0 +1,248 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { JwtDecoderUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
5
+
6
+ const slug = 'jwt-decoder-parser-and-claims-inspector';
7
+ const title = 'JWT Decoder, Parser and Claims Inspector';
8
+ const description = 'JSON Web Tokenを貼り付けて、ヘッダーとペイロードを即座にデコードし、登録されたクレームを検査し、期限切れトークンを見つけ、認証フローをデバッグするためにクリーンなJSONをコピーします。';
9
+
10
+ const howTo = [
11
+ {
12
+ name: 'JWTを貼り付ける',
13
+ text: 'Authorizationヘッダー、Cookie、ログエントリ、またはIDプロバイダからトークンをコピーして入力フィールドに貼り付けます。',
14
+ },
15
+ {
16
+ name: 'デコードされたヘッダーとペイロードを読む',
17
+ text: 'このツールはトークンをヘッダー、ペイロード、署名に分割し、JSONセグメントを別々のパネルに表示して素早く検査します。',
18
+ },
19
+ {
20
+ name: '重要なクレームをチェックする',
21
+ text: 'アルゴリズム、発行者、オーディエンス、サブジェクト、発行時刻、有効開始時刻、有効期限を、Unixタイムスタンプを手動で変換することなく確認します。',
22
+ },
23
+ {
24
+ name: '必要なデータをコピーする',
25
+ text: 'チームとサニタイズされたデバッグスナップショットを共有する必要がある場合に、デコードされた1つのセクションまたは完全なデコード済み出力をコピーします。',
26
+ },
27
+ ];
28
+
29
+ const faq = [
30
+ {
31
+ question: 'JWTをデコードすることでトークンが有効であることを証明できますか?',
32
+ answer: 'いいえ。デコードはbase64urlエンコードされたヘッダーとペイロードを明らかにするだけです。トークンが信頼できるのは、アプリケーションまたはIDプロバイダによって署名、発行者、オーディエンス、有効期限、および関連クレームが検証された後だけです。',
33
+ },
34
+ {
35
+ question: 'このJWTデコーダをアクセストークンとIDトークンに使用できますか?',
36
+ answer: 'はい。このデコーダは、標準の3部構成のJWT形式を使用している限り、OAuthアクセストークン、OpenID Connect IDトークン、セッショントークン、サービス間トークンの検査に役立ちます。',
37
+ },
38
+ {
39
+ question: '署名パネルがトークンを検証しないのはなぜですか?',
40
+ answer: 'JWT検証には、正しいシークレット、公開鍵、またはJWKS設定が必要です。このツールは、可視の署名文字列が有効性の証明であるかのように装うことなく、開発者がトークンの内容を確認できるように、意図的にデコードと検査に焦点を当てています。',
41
+ },
42
+ {
43
+ question: 'JWTをデバッグする際に最初に何をチェックすべきですか?',
44
+ answer: 'exp、nbf、iss、aud、algから始めます。実際の本番環境の問題のほとんどは、期限切れトークン、クロックスキュー、誤ったオーディエンス値、予期しない発行者URL、または安全でないアルゴリズムの仮定に起因します。',
45
+ },
46
+ ];
47
+
48
+ const ui: JwtDecoderUI = {
49
+ tokenLabel: 'JWTトークン',
50
+ tokenPlaceholder: 'ここにJWTを貼り付け: header.payload.signature',
51
+ sampleButton: 'サンプルを読み込む',
52
+ clearButton: 'クリア',
53
+ statusWaiting: 'JSONヘッダー、ペイロード、クレームをデコードするためにトークンを貼り付けてください。',
54
+ statusValid: 'JWTが正常にデコードされました。',
55
+ statusInvalid: 'これは有効な3部構成のJWTではないようです。',
56
+ statusExpired: 'JWTはデコードされましたが、expクレームが既に期限切れです。',
57
+ statusUnsigned: 'JWTはデコードされましたが、署名されていないか、alg noneを使用しています。',
58
+ headerTitle: 'ヘッダー',
59
+ payloadTitle: 'ペイロード',
60
+ signatureTitle: '署名',
61
+ claimsTitle: '登録クレーム',
62
+ copyHeader: 'デコードされたヘッダーをコピー',
63
+ copyPayload: 'デコードされたペイロードをコピー',
64
+ copySignature: '署名をコピー',
65
+ copyAll: 'すべてコピー',
66
+ copiedLabel: 'コピー済み',
67
+ invalidTokenTitle: '無効なJWT',
68
+ invalidTokenBody: 'トークンにドットで区切られた3つのbase64urlセグメントがあることを確認してください。',
69
+ invalidSegmentError: 'トークンにドットで区切られた3つのbase64urlセグメントがあることを確認してください。',
70
+ invalidDecodeError: 'ヘッダーまたはペイロードを有効なJSONとしてデコードできませんでした。',
71
+ emptyJson: '{}',
72
+ signaturePresent: '署名セグメントが存在します。認証レイヤーで正しいキーを使用して検証してください。',
73
+ signatureMissing: '署名セグメントがありません',
74
+ algorithmLabel: 'アルゴリズム',
75
+ typeLabel: 'タイプ',
76
+ issuerLabel: '発行者',
77
+ subjectLabel: 'サブジェクト',
78
+ audienceLabel: 'オーディエンス',
79
+ issuedAtLabel: '発行日時',
80
+ notBeforeLabel: '有効開始日時',
81
+ expiresAtLabel: '有効期限',
82
+ claimMissing: '存在しません',
83
+ privacyNote: 'デコードはブラウザセッション内で実行されます。セキュリティポリシーで許可されている場合を除き、本番環境のシークレットをツールに貼り付けないでください。',
84
+ sampleToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnYW1lYm9iLXVzZXItNDIiLCJuYW1lIjoiR2FtZUJvYiBEZXZlbG9wZXIiLCJpc3MiOiJodHRwczovL3d3dy5nYW1lYm9iLmRldiIsImF1ZCI6ImRldmVsb3Blci10b29scyIsImlhdCI6MTcxNzIwMDAwMCwibmJmIjoxNzE3MjAwMDAwLCJleHAiOjE4OTM0NTYwMDAsInJvbGUiOiJhZG1pbiJ9.demo-signature',
85
+ };
86
+
87
+ const faqSchema: WithContext<FAQPage> = {
88
+ '@context': 'https://schema.org',
89
+ '@type': 'FAQPage',
90
+ mainEntity: faq.map((item) => ({
91
+ '@type': 'Question',
92
+ name: item.question,
93
+ acceptedAnswer: {
94
+ '@type': 'Answer',
95
+ text: item.answer,
96
+ },
97
+ })),
98
+ };
99
+
100
+ const howToSchema: WithContext<HowTo> = {
101
+ '@context': 'https://schema.org',
102
+ '@type': 'HowTo',
103
+ name: title,
104
+ description,
105
+ step: howTo.map((step, index) => ({
106
+ '@type': 'HowToStep',
107
+ position: index + 1,
108
+ name: step.name,
109
+ text: step.text,
110
+ })),
111
+ };
112
+
113
+ const appSchema: WithContext<SoftwareApplication> = {
114
+ '@context': 'https://schema.org',
115
+ '@type': 'SoftwareApplication',
116
+ name: title,
117
+ description,
118
+ applicationCategory: 'DeveloperApplication',
119
+ operatingSystem: 'Any',
120
+ offers: {
121
+ '@type': 'Offer',
122
+ price: '0',
123
+ priceCurrency: 'EUR',
124
+ },
125
+ inLanguage: 'ja',
126
+ };
127
+
128
+ export const content: ToolLocaleContent<JwtDecoderUI> = {
129
+ slug,
130
+ title,
131
+ description,
132
+ ui,
133
+ faqTitle: 'JWTデコーダ FAQ',
134
+ faq,
135
+ bibliographyTitle: 'JWT仕様とセキュリティリファレンス',
136
+ bibliography,
137
+ howTo,
138
+ schemas: [appSchema, faqSchema, howToSchema],
139
+ seo: [
140
+ {
141
+ type: 'title',
142
+ text: 'セキュリティコンテキストを失わずにJWTをデコードする',
143
+ level: 2,
144
+ },
145
+ {
146
+ type: 'paragraph',
147
+ html: 'JSON Web Tokenはコンパクトに見えますが、署名アルゴリズム、発行者、オーディエンス、サブジェクト、発行時刻、有効開始時刻、有効期限、アプリケーション固有の認証クレームなど、認証失敗を説明する正確な詳細を含んでいることがよくあります。この<strong>JWTデコーダ、パーサ、クレームインスペクタ</strong>は、3つのトークンセグメントを読み取り可能なJSONに変換し、認証フローをより速くデバッグできるようにします。',
148
+ },
149
+ {
150
+ type: 'diagnostic',
151
+ variant: 'warning',
152
+ title: 'デコード済みは信頼済みを意味しません',
153
+ html: '誰でもJWTをbase64urlデコードできます。信頼が始まるのは、アプリケーションが正しいシークレット、公開鍵、またはJWKSで署名を検証し、発行者、オーディエンス、有効期限、およびドメイン固有のクレームを検証した後だけです。このツールはデータの検査に使用し、トークンを本物として受け入れるために使用しないでください。',
154
+ },
155
+ {
156
+ type: 'title',
157
+ text: '各JWTセグメントが教えてくれること',
158
+ level: 3,
159
+ },
160
+ {
161
+ type: 'table',
162
+ headers: ['セグメント', '一般的な内容', 'デバッグの価値'],
163
+ rows: [
164
+ ['ヘッダー', 'アルゴリズム、トークンタイプ、オプションのキーID', 'HS256、RS256、ES256など、どの検証戦略をトークンが期待しているかを示します。'],
165
+ ['ペイロード', '登録クレームとアプリケーションクレーム', 'ID、テナント、スコープ、ロール、有効期限、オーディエンスの不一致を明らかにします。'],
166
+ ['署名', 'base64urlエンコードされた暗号署名バイト', '署名セグメントが存在することを確認しますが、別の場所で正しいキーで検証する必要があります。'],
167
+ ],
168
+ },
169
+ {
170
+ type: 'title',
171
+ text: '認証の不具合を通常説明するクレーム',
172
+ level: 3,
173
+ },
174
+ {
175
+ type: 'list',
176
+ items: [
177
+ '<strong>exp:</strong> トークンの有効期限が切れている場合、更新ロジックまたはクロック設定が間違っている可能性があります。',
178
+ '<strong>nbf:</strong> トークンがまだ有効でない場合、サーバーとIDプロバイダのクロックが同期していない可能性があります。',
179
+ '<strong>iss:</strong> 発行者URLが設定と異なる場合、トークンが間違ったテナントまたは環境から来ている可能性があります。',
180
+ '<strong>aud:</strong> オーディエンスがAPI識別子と一致しない場合、トークンは別のリソース用に発行されています。',
181
+ '<strong>alg:</strong> アルゴリズムが予期しない場合、検証ツールがトークンを拒否するか、危険な設定ミスを露呈する可能性があります。',
182
+ ],
183
+ },
184
+ {
185
+ type: 'title',
186
+ text: '開発中のJWTパーサのユースケース',
187
+ level: 3,
188
+ },
189
+ {
190
+ type: 'comparative',
191
+ columns: 3,
192
+ items: [
193
+ {
194
+ title: 'フロントエンドデバッグ',
195
+ description: 'ログイン後に受け取ったIDトークンとアクセストークンを検査し、スコープ、ロール、プロフィールクレームを確認します。',
196
+ icon: 'mdi:monitor-dashboard',
197
+ points: ['プロフィールクレームをチェック', 'スコープとロールを確認', 'ログイン環境を比較'],
198
+ },
199
+ {
200
+ title: 'バックエンドAPI QA',
201
+ description: '期待される発行者とオーディエンスの値を、Authorizationヘッダーで実際に送信されたトークンと比較します。',
202
+ icon: 'mdi:api',
203
+ highlight: true,
204
+ points: ['オーディエンスの形式を検証', '発行者の不一致を見つける', 'ベアラートークンを検査'],
205
+ },
206
+ {
207
+ title: 'IDプロバイダ設定',
208
+ description: 'Auth0、Azure AD、Cognito、Keycloak、またはカスタムプロバイダからのクレームが、アプリが期待する形状になっているか確認します。',
209
+ icon: 'mdi:account-key',
210
+ points: ['テナントデータを確認', 'カスタムクレームをチェック', 'プロバイダマッピングを比較'],
211
+ },
212
+ ],
213
+ },
214
+ {
215
+ type: 'title',
216
+ text: 'このインスペクタで明らかになる一般的なJWTの失敗',
217
+ level: 3,
218
+ },
219
+ {
220
+ type: 'proscons',
221
+ title: '迅速なチェック vs 信頼の判断',
222
+ items: [
223
+ {
224
+ pro: '不正な形式のトークンを即座に確認できます。',
225
+ con: '期待するオーディエンスや発行者を知ることはできません。',
226
+ },
227
+ {
228
+ pro: 'Unixタイムスタンプクレームを読み取り可能な日付に変換します。',
229
+ con: '実際のキー素材なしでは署名を検証できません。',
230
+ },
231
+ {
232
+ pro: '発行者、オーディエンス、サブジェクト、タイプの欠落値を見つけます。',
233
+ con: 'スコープとロールがアプリケーションにとって安全であることを証明できません。',
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ type: 'summary',
239
+ title: 'ベストプラクティスワークフロー',
240
+ items: [
241
+ 'クライアントまたはAPIが実際に受け取った内容を理解するためにトークンをデコードします。',
242
+ 'アプリケーションロジックを追う前にexp、nbf、iss、aud、sub、algをチェックします。',
243
+ '署名と信頼の判断は認証レイヤーでのみ検証します。',
244
+ '機密性の高い本番JWTをチケット、ログ、スクリーンショットで共有しないでください。',
245
+ ],
246
+ },
247
+ ],
248
+ };