File size: 3,111 Bytes
025f5c0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Credential Verifier</title>
  <style>
    body { font-family: sans-serif; margin: 2rem; }
    .container { max-width: 800px; margin: 0 auto; }
    .verified { border: 2px solid green; padding: 1rem; }
    .invalid { border: 2px solid red; padding: 1rem; }
    pre { white-space: pre-wrap; word-wrap: break-word; }
  </style>
</head>
<body>
  <div class="container">
    <h1>Credential Verifier</h1>
    <div id="result"></div>
  </div>

  <script type="module">
    import * as jose from '/vendor/jose/index.js';

    const resultDiv = document.getElementById('result');

    async function verify() {
      try {
        const urlParams = new URLSearchParams(window.location.search);
        const vcJwt = urlParams.get('vc');
        if (!vcJwt) {
          throw new Error('No Verifiable Credential JWT found in the URL.');
        }

        // Fetch the institution's public key (JWK)
        const response = await fetch('/.well-known/jwks.json');
        const jwks = await response.json();
        const publicKey = await jose.importJWK(jwks.keys[0], 'ES256');

        // Verify the JWT
        const { payload, protectedHeader } = await jose.jwtVerify(vcJwt, publicKey, {
          issuer: 'did:web:example.com'
        });

        // Display the verified credential
        resultDiv.className = 'verified';
        resultDiv.innerHTML = `
          <h2>✓ Credential Verified</h2>
          <p>The signature is valid and the credential was issued by a trusted authority.</p>
          <h3>Credential Details:</h3>
          <pre>${JSON.stringify(payload, null, 2)}</pre>
          <div id="proof-of-work"></div>
        `;

        // Deep Verification
        const proofOfWorkCID = payload.vc.credentialSubject.proofOfWorkCID;
        if (proofOfWorkCID) {
          const proofDiv = document.getElementById('proof-of-work');
          proofDiv.innerHTML = '<h3>Loading Proof of Work...</h3>';
          try {
            const manifestUrl = `https://ipfs.io/ipfs/${proofOfWorkCID}`;
            const manifestResponse = await fetch(manifestUrl);
            const manifest = await manifestResponse.json();

            const itemsHtml = manifest.items.map(item =>
              `<li><a href="https://ipfs.io/ipfs/${item.cid}" target="_blank">${item.metadata.title || 'Untitled'}</a></li>`
            ).join('');

            proofDiv.innerHTML = `
              <h3>✓ Proof of Work Found</h3>
              <p>This credential is linked to the following archived work:</p>
              <ul>${itemsHtml}</ul>
            `;
          } catch (e) {
            proofDiv.innerHTML = '<h3>✗ Error loading Proof of Work.</h3>';
          }
        }

      } catch (error) {
        console.error('Verification failed:', error);
        resultDiv.className = 'invalid';
        resultDiv.innerHTML = `
          <h2>✗ Verification Failed</h2>
          <p>${error.message}</p>
        `;
      }
    }

    verify();
  </script>
</body>
</html>