89 lines
4.8 KiB
HTML
89 lines
4.8 KiB
HTML
{{template "base" .}}
|
|
|
|
{{define "content"}}
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-7 col-lg-6">
|
|
<div class="card shadow">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="bi bi-shield-lock me-2" aria-hidden="true"></i>2段階認証の設定</h5>
|
|
</div>
|
|
<div class="card-body p-4">
|
|
{{if .error}}
|
|
<div class="alert alert-danger" role="alert">{{.error}}</div>
|
|
{{end}}
|
|
|
|
<div class="alert alert-info" role="note">
|
|
<i class="bi bi-info-circle me-1" aria-hidden="true"></i>
|
|
Google Authenticator、Authy などの認証アプリを使用してください。
|
|
</div>
|
|
|
|
<h6 class="fw-bold mb-3">手順</h6>
|
|
<ol class="mb-4">
|
|
<li class="mb-2">認証アプリを開き、新しいアカウントを追加してください。</li>
|
|
<li class="mb-2">下のQRコードをスキャンするか、シークレットキーを手動で入力してください。</li>
|
|
<li class="mb-2">アプリに表示された6桁のコードを下の欄に入力して確認してください。</li>
|
|
</ol>
|
|
|
|
<div class="text-center mb-4">
|
|
<img src="data:image/png;base64,{{.qrCode}}" alt="2段階認証設定用QRコード" class="border rounded" style="max-width:200px">
|
|
<p class="text-muted small mt-2">QRコードを再スキャンしたい場合はページを再読み込みしてください。</p>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label fw-bold" for="secretKey">シークレットキー(手動入力の場合)</label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control font-monospace" id="secretKey" value="{{.secret}}" readonly aria-label="シークレットキー">
|
|
<button class="btn btn-outline-secondary" type="button" id="copySecretBtn" aria-label="シークレットキーをコピー">
|
|
<i class="bi bi-clipboard" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
<div class="form-text">認証アプリで「手動入力」を選択し、このキーを入力してください。</div>
|
|
</div>
|
|
|
|
<form method="POST" action="/profile/totp/setup">
|
|
{{.csrfField}}
|
|
<div class="mb-3">
|
|
<label for="totp_password" class="form-label fw-bold">現在のパスワード</label>
|
|
<input type="password" class="form-control" id="totp_password" name="password" placeholder="パスワードを入力" required autocomplete="current-password">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="totp_code" class="form-label fw-bold">認証コードで確認</label>
|
|
<input type="text" class="form-control form-control-lg text-center" id="totp_code" name="totp_code" placeholder="000000" maxlength="6" pattern="[0-9]{6}" inputmode="numeric" autocomplete="off" autofocus required>
|
|
<div class="form-text">認証アプリに表示された6桁のコードを入力してください。</div>
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-shield-check me-1" aria-hidden="true"></i>有効化
|
|
</button>
|
|
<a href="/profile" class="btn btn-outline-secondary">キャンセル</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "scripts"}}
|
|
<script>
|
|
document.getElementById('copySecretBtn').addEventListener('click', function() {
|
|
var btn = this;
|
|
var val = document.getElementById('secretKey').value;
|
|
if (!navigator.clipboard) {
|
|
showCopyFeedback('クリップボードがサポートされていません。手動でコピーしてください。');
|
|
return;
|
|
}
|
|
navigator.clipboard.writeText(val).then(function() {
|
|
btn.innerHTML = '<i class="bi bi-check-lg" aria-hidden="true"></i>';
|
|
btn.setAttribute('aria-label', 'コピーしました');
|
|
setTimeout(function() {
|
|
btn.innerHTML = '<i class="bi bi-clipboard" aria-hidden="true"></i>';
|
|
btn.setAttribute('aria-label', 'シークレットキーをコピー');
|
|
}, 2000);
|
|
}).catch(function(err) {
|
|
showCopyFeedback('コピーに失敗しました: ' + (err.message || err));
|
|
});
|
|
});
|
|
</script>
|
|
{{end}}
|