Files
archived-vdo.ninja/changepassword.html
2025-03-03 13:21:22 -05:00

349 lines
11 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>VDO.Ninja Hash Generator</title>
<meta charset="utf8" />
<style>
:root {
--primary: #00ff00;
--primary-dark: #00cc00;
--bg-dark: #141926;
--bg-darker: #0d1117;
--bg-card: #1e2738;
--bg-input: #2a364d;
--border: #3a465d;
--text: #ffffff;
--text-muted: #8b949e;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: var(--bg-dark);
color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
width: 100%;
}
.header {
text-align: center;
margin-bottom: 2rem;
padding: 2rem 0;
background: var(--bg-darker);
border-bottom: 1px solid var(--border);
}
h1 {
color: var(--primary);
margin-bottom: 1rem;
font-size: 2.5rem;
}
.subtitle {
color: var(--text-muted);
font-size: 1.1rem;
}
.card {
background: var(--bg-card);
padding: 1.5rem;
border-radius: 8px;
margin-bottom: 1.5rem;
border: 1px solid var(--border);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.input-group {
margin-bottom: 1rem;
}
label {
display: block;
margin-bottom: 0.5rem;
color: var(--text-muted);
}
.input-wrapper {
position: relative;
display: flex;
gap: 0.5rem;
}
input {
flex: 1;
padding: 0.75rem;
background: var(--bg-input);
border: 1px solid var(--border);
color: var(--text);
border-radius: 4px;
font-size: 1rem;
transition: all 0.2s ease;
}
input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 2px rgba(0, 255, 0, 0.1);
}
button {
background: var(--primary);
color: var(--bg-dark);
border: none;
padding: 0.75rem 1.5rem;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
font-size: 1rem;
transition: all 0.2s ease;
white-space: nowrap;
}
button:hover {
background: var(--primary-dark);
transform: translateY(-1px);
}
button:active {
transform: translateY(0);
}
.result {
display: none;
animation: fadeIn 0.3s ease;
}
.result.visible {
display: block;
}
.hash-display {
display: flex;
align-items: center;
gap: 1rem;
background: var(--bg-input);
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.hash-value {
font-family: monospace;
font-size: 1.2rem;
color: var(--primary);
}
.url-preview {
font-family: monospace;
background: var(--bg-input);
padding: 1rem;
border-radius: 4px;
word-break: break-all;
}
.info {
color: var(--text-muted);
}
.info h3 {
color: var(--text);
margin-bottom: 1rem;
}
.info p {
margin-bottom: 1rem;
}
code {
background: var(--bg-input);
padding: 0.2rem 0.4rem;
border-radius: 3px;
font-family: monospace;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.toggle-password {
position: absolute;
right: 0.5rem;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
padding: 0.5rem;
}
.copy-notification {
position: fixed;
top: 1rem;
right: 1rem;
background: var(--primary);
color: var(--bg-dark);
padding: 0.75rem 1.5rem;
border-radius: 4px;
display: none;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@media (max-width: 600px) {
.container {
padding: 1rem;
}
h1 {
font-size: 2rem;
}
.input-wrapper {
flex-direction: column;
}
button {
width: 100%;
}
}
</style>
</head>
<body>
<div class="header">
<h1>VDO.Ninja Hash Generator</h1>
<p class="subtitle">Generate secure hash values for your VDO.Ninja rooms and streams</p>
</div>
<div class="container">
<div class="card">
<div class="input-group">
<label for="passwordInput">VDO.Ninja Password</label>
<div class="input-wrapper">
<input type="password" id="passwordInput" placeholder="Enter your VDO.Ninja password" autocomplete="off">
<button onclick="togglePassword()">Show</button>
<button onclick="generateHashFromInput()">Generate Hash</button>
</div>
</div>
<div class="result" id="resultDiv">
<div class="hash-display">
<span>Hash:</span>
<span class="hash-value" id="hashResult"></span>
<button onclick="copyHash()">Copy Hash</button>
</div>
<div class="url-preview" id="urlPreview"></div>
</div>
</div>
<div class="card info">
<h3>About Hash Generation</h3>
<p>This tool generates a hash value that can be used with VDO.Ninja's <code>&hash</code> parameter instead of using <code>&password</code>. The hash provides a secure way to verify passwords without exposing the actual password in the URL.</p>
<p>Using a hash instead of a password in your URL:</p>
<p>❌ Instead of: <code>vdo.ninja/?room=yourroom&password=yourpassword</code></p>
<p>✅ Use: <code>vdo.ninja/?room=yourroom&hash=99e5</code></p>
<p>The hash value is derived from your password but doesn't contain the actual password, making it safer to share URLs while maintaining security.</p>
</div>
</div>
<div class="copy-notification" id="copyNotification">Hash copied to clipboard!</div>
<script>
function generateHash(str, length=false) {
var buffer = new TextEncoder("utf-8").encode(str);
return crypto.subtle.digest("SHA-256", buffer).then(
function(hash) {
hash = new Uint8Array(hash);
if (length) {
hash = hash.slice(0, parseInt(parseInt(length)/2));
}
return toHexString(hash);
}
);
}
function toHexString(byteArray) {
return Array.prototype.map.call(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
}
function generateHashFromInput() {
var password = document.getElementById('passwordInput').value;
if (!password) {
alert('Please enter a password');
return;
}
password = password.trim();
password = encodeURIComponent(password);
var salt = location.hostname;
if (location.hostname == "steveseguin.github.io") {
salt = "vdo.ninja";
} else if (["vdo.ninja","rtc.ninja","versus.cam","socialstream.ninja"].includes(location.hostname.split(".").slice(-2).join("."))) {
salt = location.hostname.split(".").slice(-2).join(".");
}
generateHash(password + salt, 4).then(function(hash) {
document.getElementById('hashResult').textContent = hash;
document.getElementById('urlPreview').textContent = `vdo.ninja/?room=yourroom&hash=${hash}`;
document.getElementById('resultDiv').classList.add('visible');
});
}
function copyHash() {
const hash = document.getElementById('hashResult').textContent;
navigator.clipboard.writeText(hash).then(function() {
showNotification();
});
}
function togglePassword() {
const input = document.getElementById('passwordInput');
const button = input.nextElementSibling;
if (input.type === 'password') {
input.type = 'text';
button.textContent = 'Hide';
} else {
input.type = 'password';
button.textContent = 'Show';
}
}
function showNotification() {
const notification = document.getElementById('copyNotification');
notification.style.display = 'block';
setTimeout(() => {
notification.style.display = 'none';
}, 2000);
}
// Enable Enter key to generate hash
document.getElementById('passwordInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
generateHashFromInput();
}
});
</script>
</body>
</html>