2025-05-11 08:24:46 +00:00
|
|
|
{{ define "jwt.pages.tmpl" }}
|
|
|
|
|
{{ template "head" . }}
|
2025-05-11 08:33:16 +00:00
|
|
|
<div class="section">
|
|
|
|
|
<h1 class="title is-4">🔐 Générateur de JWT pour test API WhatsApp</h1>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="label">SSOID (username)</label>
|
|
|
|
|
<div class="control">
|
|
|
|
|
<input class="input" id="ssoid" type="text" value="admin001" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="label">Clé secrète</label>
|
|
|
|
|
<div class="control">
|
|
|
|
|
<input class="input" id="secret" type="text" value="secret-key" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<button class="button is-link" onclick="generateJWT()">🔐 Générer le token</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label class="label">Résultat :</label>
|
|
|
|
|
<pre id="output" class="box" style="white-space: pre-wrap;"></pre>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button id="copyBtn" class="button is-light" onclick="copyToken()" disabled>📋 Copier le token</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
async function generateJWT() {
|
|
|
|
|
const ssoid = document.getElementById("ssoid").value;
|
|
|
|
|
const secret = document.getElementById("secret").value;
|
|
|
|
|
const exp = Math.floor(Date.now() / 1000) + 60 * 60;
|
|
|
|
|
|
|
|
|
|
const payload = {
|
|
|
|
|
username: ssoid,
|
|
|
|
|
exp: exp
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const header = {
|
|
|
|
|
alg: "HS256",
|
|
|
|
|
typ: "JWT"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const base64UrlEncode = obj => btoa(JSON.stringify(obj))
|
|
|
|
|
.replace(/=/g, '')
|
|
|
|
|
.replace(/\+/g, '-')
|
|
|
|
|
.replace(/\//g, '_');
|
|
|
|
|
|
|
|
|
|
const encode = new TextEncoder();
|
|
|
|
|
const importKey = await crypto.subtle.importKey(
|
|
|
|
|
"raw",
|
|
|
|
|
encode.encode(secret),
|
|
|
|
|
{ name: "HMAC", hash: "SHA-256" },
|
|
|
|
|
false,
|
|
|
|
|
["sign"]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const headerEncoded = base64UrlEncode(header);
|
|
|
|
|
const payloadEncoded = base64UrlEncode(payload);
|
|
|
|
|
const toSign = `${headerEncoded}.${payloadEncoded}`;
|
|
|
|
|
|
|
|
|
|
const signature = await crypto.subtle.sign("HMAC", importKey, encode.encode(toSign));
|
|
|
|
|
const signatureArray = new Uint8Array(signature);
|
|
|
|
|
const base64Signature = btoa(String.fromCharCode(...signatureArray))
|
|
|
|
|
.replace(/=/g, '')
|
|
|
|
|
.replace(/\+/g, '-')
|
|
|
|
|
.replace(/\//g, '_');
|
|
|
|
|
|
|
|
|
|
const jwt = `${toSign}.${base64Signature}`;
|
|
|
|
|
document.getElementById("output").textContent = jwt;
|
|
|
|
|
document.getElementById("copyBtn").disabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function copyToken() {
|
|
|
|
|
const token = document.getElementById("output").textContent;
|
|
|
|
|
navigator.clipboard.writeText(token).then(() => {
|
|
|
|
|
alert("✅ Token copié !");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
{{ end }}
|