Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
160 lines (148 loc) · 8.34 KB
/
Copy pathindex.html
File metadata and controls
160 lines (148 loc) · 8.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#08090d">
<meta name="description" content="Decode and inspect JWT headers, claims, and expiry with live countdowns — entirely offline. Never verifies signatures, never asks for a secret.">
<title>JWT Decoder Pro — Web Utility Suite</title>
<link rel="icon" href="assets/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="assets/css/base.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<header class="topbar container">
<a class="brand" href="https://github.com/kasapdev/web-utility-suite" aria-label="Back to Web Utility Suite">
<span class="logo" aria-hidden="true">
<!-- key / token icon -->
<svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="11" width="18" height="9" rx="2"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
<circle cx="12" cy="15.5" r="1.6"/>
</svg>
</span>
<span class="col" style="gap:0">
<span>JWT Decoder</span>
<span class="sub">Web Utility Suite</span>
</span>
</a>
<span class="spacer"></span>
<span id="statusBadge" class="badge" role="status" aria-live="polite" title="Token status">
<span class="status-dot" aria-hidden="true"></span><span id="statusText">Ready</span>
</span>
<button class="btn btn--icon" data-shortcut-help title="Keyboard shortcuts (?)" aria-label="Keyboard shortcuts">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<rect x="2" y="4" width="20" height="16" rx="2"/>
<path d="M6 8h.01M10 8h.01M14 8h.01M18 8h.01M6 12h.01M10 12h.01M14 12h.01M18 12h.01M7 16h10"/>
</svg>
</button>
<button class="btn btn--icon" data-theme-toggle title="Toggle theme" aria-label="Toggle theme">
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="4"/>
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
</svg>
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
</button>
</header>
<main class="container">
<!-- Notice -->
<section class="panel notice-panel fade-in" aria-label="Decode-only notice">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/></svg>
<p>This tool <strong>decodes and inspects</strong> a JWT locally in your browser only. It never verifies the signature and never asks for (or accepts) a secret or public key — nothing is sent anywhere.</p>
</section>
<!-- Token input -->
<section class="panel token-panel fade-in" aria-label="Token input">
<div class="pane-head">
<h2 class="pane-title">JWT</h2>
<span id="tokenStats" class="muted pane-meta mono">0 chars</span>
</div>
<textarea id="tokenInput" class="mono" spellcheck="false" autocapitalize="off" autocomplete="off"
aria-label="JWT input"
placeholder="Paste a JWT here… e.g. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature"></textarea>
<div class="toolbar">
<button id="btnClear" class="btn btn--sm btn--ghost" title="Clear everything">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/></svg>
Clear
</button>
<button id="btnSample" class="btn btn--sm btn--ghost" title="Load a sample token">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M9 13h6M9 17h6"/></svg>
Sample
</button>
</div>
</section>
<!-- Error panel -->
<section id="errorPanel" class="panel error-panel fade-in" role="alert" hidden>
<div class="error-head">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 8v4M12 16h.01"/></svg>
<strong>Invalid token</strong>
</div>
<p id="errorMsg" class="error-msg mono"></p>
</section>
<!-- Warnings -->
<div id="warnings" class="row wrap gap-2 warnings-row" hidden></div>
<!-- Claims summary -->
<section id="claimsPanel" class="panel claims-panel rise" aria-label="Claims summary" hidden>
<div class="pane-head">
<h2 class="pane-title">Claims summary</h2>
<span class="row gap-2" id="headerBadges"></span>
</div>
<div class="claims-grid" id="claimsGrid"></div>
</section>
<!-- Header / Payload -->
<section class="editor rise" aria-label="Decoded token">
<div class="pane panel pane--header">
<div class="pane-head">
<h2 class="pane-title">Header</h2>
<button id="btnCopyHeader" class="btn btn--sm" title="Copy header JSON">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
Copy
</button>
</div>
<div class="output-scroll">
<pre id="headerOutput" class="output-code mono" aria-live="polite" tabindex="0"><code id="headerCode"></code></pre>
<div id="headerEmpty" class="empty output-empty">
<p>Decoded header will appear here.</p>
</div>
</div>
</div>
<div class="pane panel pane--payload">
<div class="pane-head">
<h2 class="pane-title">Payload</h2>
<button id="btnCopyPayload" class="btn btn--sm" title="Copy payload JSON">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
Copy
</button>
</div>
<div class="output-scroll">
<pre id="payloadOutput" class="output-code mono" aria-live="polite" tabindex="0"><code id="payloadCode"></code></pre>
<div id="payloadEmpty" class="empty output-empty">
<p>Decoded payload will appear here.</p>
</div>
</div>
</div>
</section>
</main>
<footer class="app-footer container">
Part of the <a href="https://github.com/kasapdev/web-utility-suite">Web Utility Suite</a> · MIT Licensed
</footer>
<!-- Shortcuts help modal -->
<div id="helpBackdrop" class="modal-backdrop" hidden>
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="helpTitle">
<div class="row between center" style="margin-bottom:var(--space-4)">
<h3 id="helpTitle" style="margin:0">Keyboard shortcuts</h3>
<button id="helpClose" class="btn btn--icon btn--ghost" aria-label="Close">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>
</button>
</div>
<table class="shortcut-table">
<tbody id="shortcutRows"></tbody>
</table>
<p class="muted" style="margin:var(--space-4) 0 0;font-size:13px">Tip: <kbd>mod</kbd> means <kbd>Ctrl</kbd> on Windows/Linux and <kbd>⌘</kbd> on macOS.</p>
</div>
</div>
<script src="assets/js/core.js"></script>
<script src="js/app.js"></script>
</body>
</html>