Add electronic signature

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-02-16 23:12:09 +01:00
parent e6f9d7aae2
commit c191d25e9a
58 changed files with 7557 additions and 292 deletions

View File

@@ -0,0 +1,520 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 9.5px;
color: #000;
line-height: 1.4;
}
/* -- Top bar -- */
.top-bar {
border-top: 4px solid #000;
padding-top: 10px;
margin-bottom: 6px;
display: table;
width: 100%;
}
.top-bar-left {
display: table-cell;
vertical-align: top;
}
.top-bar-right {
display: table-cell;
vertical-align: top;
text-align: right;
width: 120px;
}
.brand {
font-size: 14px;
font-weight: 700;
color: #000;
letter-spacing: 0.5px;
}
.cert-title {
font-size: 16px;
font-weight: 700;
font-style: italic;
color: #000;
border-bottom: 2px solid #000;
padding-bottom: 4px;
display: inline-block;
margin-bottom: 6px;
}
/* -- Meta line (ID + Status) -- */
.meta-line {
display: table;
width: 100%;
margin-bottom: 2px;
font-size: 9.5px;
}
.meta-left {
display: table-cell;
vertical-align: top;
}
.meta-right {
display: table-cell;
vertical-align: top;
text-align: right;
}
/* -- Info rows -- */
.info-row {
font-size: 9.5px;
line-height: 1.5;
margin-bottom: 1px;
}
/* -- Info grid (multi-column) -- */
.info-grid {
display: table;
width: 100%;
margin-bottom: 2px;
}
.info-col {
display: table-cell;
vertical-align: top;
font-size: 9.5px;
line-height: 1.5;
}
.info-col-left {
width: 38%;
}
.info-col-mid {
width: 30%;
}
.info-col-right {
width: 32%;
}
/* -- Section header bar -- */
.section-bar {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
}
.section-bar td {
padding: 5px 6px;
font-size: 9.5px;
font-weight: 700;
color: #000;
background: #e8e8e8;
border-top: 2px solid #000;
}
/* -- Signer content -- */
.signer-table {
width: 100%;
border-collapse: collapse;
}
.signer-table td {
padding: 6px 6px;
vertical-align: top;
font-size: 9.5px;
line-height: 1.5;
}
.signer-name {
font-weight: 700;
font-size: 9.5px;
}
/* -- Events table -- */
.events-table {
width: 100%;
border-collapse: collapse;
font-size: 9px;
}
.events-table thead td {
padding: 5px 6px;
font-weight: 700;
color: #000;
background: #e8e8e8;
border-top: 2px solid #000;
}
.events-table tbody td {
padding: 4px 6px;
border-bottom: 1px solid #ddd;
font-size: 9px;
}
/* -- Detail table (key-value) -- */
.detail-table {
width: 100%;
border-collapse: collapse;
}
.detail-table td {
padding: 3px 6px;
vertical-align: top;
font-size: 9px;
border-bottom: 1px solid #ddd;
}
.detail-table .lbl {
width: 170px;
font-weight: 700;
color: #333;
}
/* -- Mono -- */
.mono {
font-family: "Courier New", Courier, monospace;
font-size: 8.5px;
word-break: break-all;
}
/* -- Consent -- */
.consent-box {
padding: 6px;
font-size: 9px;
line-height: 1.6;
color: #333;
border-bottom: 1px solid #ddd;
}
/* -- Verification -- */
.verification-box {
padding: 6px;
font-size: 9px;
line-height: 1.6;
color: #333;
}
.verification-box ol {
margin: 4px 0 0 18px;
padding: 0;
}
/* -- ERSD -- */
.ersd-section {
page-break-before: always;
}
.ersd-title {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
color: #000;
border-bottom: 2px solid #000;
padding-bottom: 4px;
margin-bottom: 10px;
}
.ersd-body {
font-size: 9.5px;
color: #000;
line-height: 1.7;
}
.ersd-body p {
margin-bottom: 6px;
}
.ersd-body h3 {
font-size: 9.5px;
font-weight: 700;
margin-top: 10px;
margin-bottom: 2px;
}
.ersd-body ul {
margin: 2px 0 6px 18px;
padding: 0;
}
/* -- Footer -- */
.footer {
margin-top: 16px;
padding-top: 6px;
border-top: 1px solid #999;
font-size: 8px;
color: #777;
line-height: 1.5;
}
</style>
</head>
<body>
<!-- Top bar with title and brand -->
<div class="top-bar">
<div class="top-bar-left">
<div class="cert-title">Certificate Of Completion</div>
</div>
<div class="top-bar-right">
<div class="brand">probo</div>
</div>
</div>
<!-- Signature ID + Status -->
<div class="meta-line">
<div class="meta-left">
Signature Id: {{.SignatureID}}
</div>
<div class="meta-right">
<strong>Status: Completed</strong>
</div>
</div>
<!-- Subject -->
<div class="info-row">
<strong>Subject:</strong> {{.DocumentTypeName}}
</div>
<!-- Document / Source info grid -->
<div class="info-grid" style="margin-top: 4px;">
<div class="info-col info-col-left">
<div>Document Type: {{.DocumentType}}</div>
<div>File Hash (SHA-256):</div>
<div class="mono">{{.FileHash}}</div>
</div>
<div class="info-col info-col-mid">
&nbsp;
</div>
<div class="info-col info-col-right">
<div>Organization Id:</div>
<div class="mono">{{.OrganizationID}}</div>
<div style="margin-top: 2px;">File Id:</div>
<div class="mono">{{.FileID}}</div>
</div>
</div>
<!-- Signer Events -->
<table class="section-bar">
<tr>
<td style="width: 40%;">Signer Events</td>
<td style="width: 60%;">Timestamp</td>
</tr>
</table>
<table class="signer-table">
<tr>
<td style="width: 40%;">
<div class="signer-name">{{.SignerFullName}}</div>
<div>{{.SignerEmail}}</div>
<div>Security Level: Email, Account Authentication</div>
<div>Using IP Address: {{.SignerIPAddress}}</div>
<div style="margin-top: 6px; font-size: 8.5px;">
<strong>Electronic Record and Signature Disclosure:</strong><br/>
Accepted
</div>
</td>
<td style="width: 60%;">
<div><strong>Signed:</strong> {{.SignedAt}}</div>
<div style="margin-top: 8px; font-size: 8.5px;">
User Agent: {{.SignerUserAgent}}
</div>
</td>
</tr>
</table>
<!-- Electronic Consent -->
<table class="section-bar">
<tr>
<td>Electronic Consent</td>
</tr>
</table>
<div class="consent-box">{{.ConsentText}}</div>
<!-- Signing Summary Events -->
<table class="events-table">
<thead>
<tr>
<td>Signing Summary Events</td>
<td>Status</td>
<td>Timestamps</td>
</tr>
</thead>
<tbody>
{{range .Events}}
<tr>
<td>{{.EventType}}</td>
<td>{{.Source}}</td>
<td>{{.OccurredAt}}</td>
</tr>
{{end}}
</tbody>
</table>
<!-- Integrity Verification -->
<table class="section-bar">
<tr>
<td>Integrity Verification</td>
</tr>
</table>
<table class="detail-table">
<tr>
<td class="lbl">Seal (SHA-256, v{{.SealVersion}})</td>
<td><span class="mono">{{.Seal}}</span></td>
</tr>
{{if .TSAAuthority}}
<tr>
<td class="lbl">TSA Authority</td>
<td>{{.TSAAuthority}}</td>
</tr>
{{end}}
{{if .TSATime}}
<tr>
<td class="lbl">TSA Timestamp</td>
<td>{{.TSATime}}</td>
</tr>
{{end}}
{{if .TSASerial}}
<tr>
<td class="lbl">TSA Serial Number</td>
<td>{{.TSASerial}}</td>
</tr>
{{end}}
</table>
<!-- Seal Verification -->
<table class="section-bar">
<tr>
<td>Seal Verification (v{{.SealVersion}})</td>
</tr>
</table>
<div class="verification-box">
To independently verify the integrity seal, compute the SHA-256 hash of
the following fields joined by newline characters (<span class="mono">\n</span>),
in this exact order:
<ol>
<li>Signature ID</li>
<li>Organization ID</li>
<li>Document Type (the raw value, e.g. <span class="mono">NDA</span>)</li>
<li>File ID</li>
<li>File Hash (SHA-256, lowercase hex)</li>
<li>Signer Full Name</li>
<li>Signer Email (lowercased)</li>
<li>Signer IP Address</li>
<li>Signer User Agent</li>
<li>Consent Text (the full text shown above)</li>
<li>Signed At (UTC, RFC 3339 with nanoseconds, truncated to microsecond precision)</li>
</ol>
<div style="margin-top: 4px;">
The resulting lowercase hex-encoded SHA-256 digest must match the seal
shown above.
</div>
</div>
<!-- Electronic Record and Signature Disclosure -->
<div class="ersd-section">
<div class="ersd-title">Electronic Record and Signature Disclosure</div>
<div class="ersd-body">
<p>
From time to time, the organization identified in this certificate (we, us, or
the Company) may be required by law to provide to you certain written notices or
disclosures. Described below are the terms and conditions for providing to you
such notices and disclosures electronically through the Probo platform. Please
read the information below carefully and thoroughly.
</p>
<h3>Withdrawing your consent</h3>
<p>
If you decide to receive notices and disclosures from us electronically, you may
at any time change your mind and tell us that you wish to withdraw your consent to
receive notices and disclosures electronically. How you must inform us of your
decision is described below.
</p>
<h3>All notices and disclosures will be sent to you electronically</h3>
<p>
Unless you tell us otherwise in accordance with the procedures described herein, we
will provide electronically to you through the Probo platform all required notices,
disclosures, authorizations, acknowledgements, and other documents that are required
to be provided or made available to you during the course of our relationship with
you. To reduce the chance of you inadvertently not receiving any notice or
disclosure, we prefer to provide all of the required notices and disclosures to you
by the same method and to the same address that you have given us.
</p>
<h3>How to contact us</h3>
<p>
You may contact us to let us know of your changes as to how we may contact you
electronically, and to withdraw your prior consent to receive notices and
disclosures electronically. To reach us, please send an email to
<strong>legal@getprobo.com</strong>.
</p>
<h3>To advise us of your new email address</h3>
<p>
To let us know of a change in your email address where we should send notices and
disclosures electronically to you, you must send an email message to us at
legal@getprobo.com and in the body of such request you must state your previous
email address and your new email address. We do not require any other information
from you to change your email address.
</p>
<h3>To withdraw your consent</h3>
<p>
To inform us that you no longer wish to receive future notices and disclosures in
electronic format you may:
</p>
<ul>
<li>
decline to sign a document from within your signing session, and on the
subsequent page, indicate you wish to withdraw your consent; or
</li>
<li>
send us an email to legal@getprobo.com and in the body of such request you
must state your email, full name, mailing address, and telephone number. We do
not need any other information from you to withdraw consent. The consequences of
your withdrawing consent for online documents will be that transactions may take
a longer time to process.
</li>
</ul>
<h3>Acknowledging your access and consent to receive and sign documents electronically</h3>
<p>
By signing the document electronically through the Probo platform, you confirm
that:
</p>
<ul>
<li>
You can access and read this Electronic Record and Signature Disclosure; and
</li>
<li>
You can print on paper this Electronic Record and Signature Disclosure, or save
or send this Electronic Record and Signature Disclosure to a location where you
can print it, for future reference and access; and
</li>
<li>
Until or unless you notify us as described above, you consent to receive
exclusively through electronic means all notices, disclosures, authorizations,
acknowledgements, and other documents that are required to be provided or made
available to you during the course of your relationship with us.
</li>
</ul>
</div>
</div>
<!-- Footer -->
<div class="footer">
This certificate was generated automatically by Probo. The integrity
seal and TSA timestamp provide tamper-evident proof of the signing
event. All information required to independently recompute and verify
the seal is included in this document.
</div>
</body>
</html>