Files
nostr-oidc-bridge/views/login.ejs
Your Name d0845a8323 first
2025-08-17 20:07:36 -04:00

207 lines
6.5 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nostr Login - OIDC Bridge</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 500px;
margin: 50px auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.logo {
text-align: center;
margin-bottom: 30px;
color: #333;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #333;
}
input, textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
textarea {
height: 100px;
resize: vertical;
font-family: monospace;
}
.challenge {
background-color: #f8f9fa;
padding: 15px;
border-radius: 4px;
border-left: 4px solid #007bff;
margin-bottom: 20px;
word-break: break-all;
font-family: monospace;
font-size: 12px;
}
.button {
background-color: #007bff;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
width: 100%;
margin-bottom: 10px;
}
.button:hover {
background-color: #0056b3;
}
.button.secondary {
background-color: #6c757d;
}
.button.secondary:hover {
background-color: #545b62;
}
.error {
color: #dc3545;
background-color: #f8d7da;
border: 1px solid #f5c6cb;
padding: 10px;
border-radius: 4px;
margin-bottom: 20px;
}
.help-text {
font-size: 12px;
color: #6c757d;
margin-top: 5px;
}
.or-divider {
text-align: center;
margin: 20px 0;
position: relative;
}
.or-divider::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: #ddd;
}
.or-divider span {
background: white;
padding: 0 15px;
color: #6c757d;
}
</style>
</head>
<body>
<div class="container">
<div class="logo">
<h2>🔑 Sign in with Nostr</h2>
<p>Authenticate using your Nostr identity</p>
</div>
<% if (typeof error !== 'undefined') { %>
<div class="error">
<strong>Error:</strong> <%= error %>
</div>
<% } %>
<div class="challenge">
<strong>Challenge to sign:</strong><br>
<%= challenge %>
</div>
<!-- Browser Extension Login -->
<button class="button" onclick="signWithExtension()">
🌐 Sign with Browser Extension
</button>
<div class="or-divider">
<span>or</span>
</div>
<!-- Manual Login Form -->
<form method="POST" action="<%= returnTo %>">
<input type="hidden" name="uid" value="<%= uid %>">
<div class="form-group">
<label for="npub">Your Nostr Public Key (npub):</label>
<input type="text" id="npub" name="npub" placeholder="npub1..." required>
<div class="help-text">Your public Nostr identity key</div>
</div>
<div class="form-group">
<label for="event_json">Signed Event (JSON):</label>
<textarea id="event_json" name="event_json" placeholder='{"kind":1,"pubkey":"...","created_at":...,"tags":[],"content":"challenge","sig":"..."}'></textarea>
<div class="help-text">Create and sign a kind 1 event with the challenge as content</div>
</div>
<button type="submit" class="button">
✍️ Verify Signature & Login
</button>
</form>
<div class="help-text" style="margin-top: 30px; text-align: center;">
<strong>Instructions:</strong><br>
1. Use a browser extension (recommended) or<br>
2. Create a Nostr event with the challenge above as content<br>
3. Sign it with your private key and paste the JSON
</div>
</div>
<script>
async function signWithExtension() {
if (!window.nostr) {
alert('No Nostr extension detected. Please install a Nostr browser extension like nos2x or Alby.');
return;
}
try {
const challenge = '<%= challenge %>';
const event = {
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: challenge
};
const signedEvent = await window.nostr.signEvent(event);
const pubkey = await window.nostr.getPublicKey();
const npub = window.NostrTools ? window.NostrTools.nip19.npubEncode(pubkey) : `npub${pubkey}`;
// Fill the form and submit
document.getElementById('npub').value = npub;
document.getElementById('event_json').value = JSON.stringify(signedEvent);
document.querySelector('form').submit();
} catch (error) {
alert('Error signing with extension: ' + error.message);
console.error('Extension signing error:', error);
}
}
// Load NostrTools if available for npub encoding
if (typeof window !== 'undefined' && !window.NostrTools) {
const script = document.createElement('script');
script.src = 'https://unpkg.com/nostr-tools/lib/nostr.bundle.js';
document.head.appendChild(script);
}
</script>
</body>
</html>