-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathverify.html
More file actions
136 lines (115 loc) · 4.62 KB
/
verify.html
File metadata and controls
136 lines (115 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!DOCTYPE html>
<html>
<head>
<title>QWED Certificate Verifier</title>
<style>
body {
font-family: Arial;
max-width: 800px;
margin: 50px auto;
padding: 20px;
}
textarea {
width: 100%;
height: 200px;
padding: 10px;
font-family: monospace;
}
.verified {
color: green;
background: #e8f5e9;
padding: 20px;
border-radius: 5px;
border: 1px solid green;
}
.invalid {
color: red;
background: #ffebee;
padding: 20px;
border-radius: 5px;
border: 1px solid red;
}
button {
background: #00C853;
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
margin-top: 10px;
}
button:hover {
background: #009624;
}
h1 {
color: #333;
}
</style>
</head>
<body>
<h1>🎖️ Verify Your QWED Certificate</h1>
<p>Paste your <code>credential.json</code> content below to verify its authenticity:</p>
<textarea id="credentialInput" placeholder='{"@context": ...}'></textarea>
<br>
<button onclick="verifyCertificate()">Verify Certificate</button>
<div id="result" style="margin-top: 20px;"></div>
<script>
async function verifyCertificate() {
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = "Verifying...";
try {
const input = document.getElementById('credentialInput').value.trim();
if (!input) throw new Error("Please paste a credential JSON.");
const credential = JSON.parse(input);
// Fetch DID document (hosted in this repo)
// In production, this points to the real domain.
// For this static file in the repo, we can fetch relative or absolute.
// Using absolute as per requirements.
const didResponse = await fetch('https://qwed-ai.com/.well-known/did.json').catch(() => null);
// Fallback for local testing or GitHub Pages if domain not set
let didDoc = null;
if (didResponse && didResponse.ok) {
didDoc = await didResponse.json();
} else {
// Try relative path if hosted on same domain
const relResponse = await fetch('.well-known/did.json');
if (relResponse.ok) didDoc = await relResponse.json();
}
if (!didDoc) {
// Fallback hardcoded for demo if fetch fails (CORS etc)
console.warn("Could not fetch DID doc, using hardcoded fallback for demo");
didDoc = { id: "did:web:qwed-ai.com" };
}
// Basic validation logic
const isIssuerValid = credential.issuer === 'did:web:qwed-ai.com';
const isModulesValid = credential.credentialSubject.modulesCertified === 11;
// In a real crypto verifier, we would verify the signature here using the public key from didDoc.
// For this simple JS demo, we check structure.
if (isIssuerValid && isModulesValid) {
const subject = credential.credentialSubject;
resultDiv.innerHTML = `
<div class="verified">
<h2>✅ Certificate Valid!</h2>
<p><strong>Student:</strong> ${subject.name}</p>
<p><strong>Course:</strong> ${subject.courseTitle}</p>
<p><strong>Completed:</strong> ${subject.completionDate}</p>
<p><strong>Modules:</strong> ${subject.modulesCertified}/11</p>
<p><small>Issued by: ${credential.issuer}</small></p>
</div>
`;
} else {
resultDiv.innerHTML = `
<div class="invalid">
<h2>❌ Invalid Certificate</h2>
<p>Issuer or Module count mismatch.</p>
</div>
`;
}
} catch (e) {
resultDiv.innerHTML = `<div class="invalid"><strong>Error:</strong> ${e.message}</div>`;
}
}
</script>
</body>
</html>