Files
sample-site/sso.html
2026-05-20 22:40:32 +09:00

132 lines
5.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>amiPro SSO</title>
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 24px; background: #f5f5f7; color: #1f2430; }
.card { background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 6px 24px rgba(0,0,0,0.06); max-width: 520px; margin: 0 auto; }
h1 { font-size: 22px; margin: 0 0 12px; }
p { margin: 0 0 12px; color: #4a5160; }
label { display: block; margin: 12px 0 6px; font-weight: 600; }
input, select, button { width: 100%; padding: 10px 12px; border-radius: 8px; border: 1px solid #cfd2dc; box-sizing: border-box; font-size: 14px; }
button { background: #6c63ff; color: #fff; border: none; cursor: pointer; margin-top: 14px; font-weight: 700; }
button.secondary { background: #e8e9ef; color: #1f2430; border: 1px solid #cfd2dc; }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.muted { font-size: 12px; color: #6c758a; }
.pill { display: inline-block; padding: 4px 10px; border-radius: 999px; background: #eef1ff; color: #3c45a0; font-size: 12px; margin-left: 6px; }
#status { margin-top: 10px; font-size: 13px; min-height: 18px; }
</style>
<script src="files/dfido2-lib.js"></script>
<script>
const PROD_URL = 'https://fido2.amipro.me';
const DEV_DEFAULT = localStorage.getItem('dfido2_dev_url') || '';
let redirectUri = '';
function setServer(url) {
if (!url) return;
setFidoServerURL(url);
document.getElementById('currentServer').textContent = url;
if (url !== PROD_URL) localStorage.setItem('dfido2_dev_url', url);
}
function init() {
const params = new URL(window.location.href).searchParams;
redirectUri = params.get('redirect_uri') || `${window.location.origin}/app-callback`;
const devInput = document.getElementById('devUrl');
devInput.value = DEV_DEFAULT;
const rpInput = document.getElementById('rpId');
rpInput.value = location.hostname;
setServer(PROD_URL);
}
function useProd() {
setServer(PROD_URL);
}
function useDev() {
const v = document.getElementById('devUrl').value.trim();
if (!v) {
setStatus('Enter a dev/ngrok URL (https://...) first.');
return;
}
setServer(v);
setStatus('Dev server set.');
}
function setStatus(msg) {
document.getElementById('status').textContent = msg || '';
}
async function doRegister() {
setStatus('Registering...');
const uid = document.getElementById('uid').value.trim();
const display = document.getElementById('display').value.trim() || uid;
const rpId = document.getElementById('rpId').value.trim() || location.hostname;
if (!uid) { setStatus('User ID required'); return; }
const result = await registerFido2(uid, display, rpId);
await handleResult(result, rpId);
}
async function doLogin() {
setStatus('Signing in...');
const uid = document.getElementById('uid').value.trim();
const rpId = document.getElementById('rpId').value.trim() || location.hostname;
if (!uid) { setStatus('User ID required'); return; }
const result = await authenticateFido2(uid, rpId);
await handleResult(result, rpId);
}
async function handleResult(result, rpId) {
if (result.status !== 'ok') {
errProcessFido2(result);
setStatus(result.errorMessage || 'Failed');
return;
}
// No server handoff: send session + username directly to redirect_uri for the app to consume.
const params = new URLSearchParams({
session: result.session,
username: result.username,
rpId: rpId || ''
});
setStatus('Success. Returning to app...');
window.location.href = `${redirectUri}?${params.toString()}`;
}
</script>
</head>
<body onload="init()">
<div class="card">
<h1>amiPro Passkey SSO <span class="pill">Beta</span></h1>
<p>Use passkeys to sign in. Choose production or your ngrok dev host.</p>
<div class="row">
<button class="secondary" onclick="useProd()">Use production</button>
<button class="secondary" onclick="useDev()">Use dev/ngrok</button>
</div>
<label for="devUrl">Dev / ngrok URL</label>
<input id="devUrl" placeholder="https://amipro-dev.ngrok-free.app" />
<p class="muted">Current server: <span id="currentServer">(not set)</span></p>
<label for="uid">User ID</label>
<input id="uid" placeholder="user@example.com" />
<label for="display">Display name (optional)</label>
<input id="display" placeholder="Name shown to user" />
<label for="rpId">rpId</label>
<input id="rpId" placeholder="fido2.amipro.me or your ngrok host" value="" />
<button onclick="doLogin()">Passwordless login</button>
<button onclick="doRegister()">Register new passkey</button>
<div id="status" class="muted"></div>
</div>
</body>
</html>