attstore / templates /webhook_form.html
dn-scribe's picture
add templating doc in webhook form
65d1f4d
Raw History Blame Contribute Delete
10.8 kB
{% extends "base.html" %}
{% block title %}{% if webhook %}Edit Webhook{% else %}Add Webhook{% endif %}{% endblock %}
{% block content %}
<div class="container my-4">
<div class="row justify-content-center">
<div class="col-lg-8 col-md-10">
<div class="card">
<div class="card-body">
<h2 class="mb-4">{% if webhook %}Edit Webhook{% else %}Add Webhook{% endif %}</h2>
<form method="post" action="{% if webhook and webhook.get('id') %}{{ url_for('web.update_webhook_ui', webhook_id=webhook.get('id')) }}{% else %}{{ url_for('web.add_webhook') }}{% endif %}">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" required value="{{ webhook.get('name') if webhook else '' }}">
</div>
<div class="mb-3">
<label for="trigger_type" class="form-label">Trigger Type</label>
<select class="form-select" id="trigger_type" name="trigger_type" required onchange="updateTriggerTypeUI()">
<option value="badge" {% if not webhook or webhook.get('trigger_type', 'badge') == 'badge' %}selected{% endif %}>Badge</option>
<option value="attestation-condition" {% if webhook and webhook.get('trigger_type') == 'attestation-condition' %}selected{% endif %}>Attestation Condition</option>
</select>
</div>
<div id="badge-trigger-section" style="{% if webhook and webhook.get('trigger_type') == 'attestation-condition' %}display:none;{% endif %}">
<div class="mb-3">
<label for="badge" class="form-label">Badge</label>
<select class="form-select" id="badge" name="badge">
{% for badge in badges %}
<option value="{{ badge.name }}" {% if webhook and webhook.get('badge') == badge.name %}selected{% endif %}>{{ badge.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="trigger_non_zero" name="trigger_non_zero" {% if webhook and webhook.get('trigger_non_zero') %}checked{% elif not webhook %}checked{% endif %}>
<label class="form-check-label" for="trigger_non_zero">
Trigger on non-zero badge count
</label>
</div>
</div>
<div id="attestation-condition-section" style="{% if not webhook or webhook.get('trigger_type', 'badge') == 'badge' %}display:none;{% endif %}">
<label class="form-label">Attestation Conditions</label>
<div id="conditions-list">
{% if webhook and webhook.get('attestation_conditions') %}
{% for cond in webhook.get('attestation_conditions') %}
<div class="row mb-2 condition-row">
<div class="col">
<input type="text" class="form-control" name="condition_field" placeholder="Field" value="{{ cond.field }}">
</div>
<div class="col">
<input type="text" class="form-control" name="condition_value" placeholder="Value (comma for list)" value="{{ cond.value }}">
</div>
<div class="col-auto">
<button type="button" class="btn btn-danger btn-sm" onclick="removeConditionRow(this)">Remove</button>
</div>
</div>
{% endfor %}
{% endif %}
</div>
<button type="button" class="btn btn-secondary btn-sm" onclick="addConditionRow()">Add Condition</button>
<small class="form-text text-muted">
Each condition is ANDed. For a list-typed context field, the value must be in the list.
</small>
</div>
<div class="mb-3">
<label for="url" class="form-label">Webhook URL</label>
<input type="url" class="form-control" id="url" name="url" required value="{{ webhook.get('url') if webhook else 'https://httpbin.org/post' }}">
</div>
<div class="mb-3">
<label for="method" class="form-label">HTTP Method</label>
<select class="form-select" id="method" name="method">
<option value="POST" {% if webhook and webhook.method == 'POST' %}selected{% endif %}>POST</option>
<option value="GET" {% if webhook and webhook.method == 'GET' %}selected{% endif %}>GET</option>
<option value="PUT" {% if webhook and webhook.method == 'PUT' %}selected{% endif %}>PUT</option>
<option value="DELETE" {% if webhook and webhook.method == 'DELETE' %}selected{% endif %}>DELETE</option>
</select>
</div>
<div class="mb-3">
<label for="headers" class="form-label">Headers (JSON)</label>
<textarea class="form-control" id="headers" name="headers" rows="3" placeholder='{"Authorization": "Bearer ..."}'>{% if webhook and webhook.headers %}{{ webhook.headers }}{% endif %}</textarea>
</div>
<div class="mb-3">
<label for="content" class="form-label">Content Template (JSON)</label>
<textarea class="form-control" id="content" name="content" rows="5" placeholder='{"key":"value", "attestation":{attestation_details}}'>{% if webhook and webhook.content %}{{ webhook.content }}{% else %}{"attestation":{attestation_details}}{% endif %}</textarea>
<small class="form-text text-muted">
<b>Templating:</b> Use variables in the form <code>--varname--</code> (two dashes, name, two dashes) anywhere in the URL, headers, or content.<br>
<b>Supported variables:</b>
<ul>
<li><code>product-key</code> (product key string), <code>product-version</code> (product version string)</li>
<li><code>attestation_raw</code> (raw file content, as bytes), <code>attestation_predicate</code> (decoded predicate), <code>attestation_predicate_base64</code> (base64-encoded predicate)</li>
<li>Any context field: <code>--contextkey--</code> (empty string if missing)</li>
<li>Labels: <code>--labels.labelname--</code> (gets value for label <code>labelname</code>, empty if not found)</li>
</ul>
<b>Examples:</b>
<ul>
<li><code>{"Authorization": "Bearer --secret--"}</code> → <code>{"Authorization": "Bearer ghpat-1232455"}</code></li>
<li><code>{"predicate": --attestation_predicate--}</code> → <code>{"predicate": { ... }}</code></li>
</ul>
If a variable is not found, it is replaced with an empty string.
</small>
</div>
<div class="mb-3">
<label for="secret" class="form-label">Secret (optional)</label>
<input type="text" class="form-control" id="secret" name="secret" value="{{ webhook.get('secret') if webhook else '' }}">
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="is_active" name="is_active" {% if webhook and webhook.get('is_active') %}checked{% elif not webhook %}checked{% endif %}>
<label class="form-check-label" for="is_active">Active</label>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">{% if webhook and webhook.get('id') %}Save Changes{% else %}Create Webhook{% endif %}</button>
<a href="{{ url_for('web.webhooks') }}" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
function updateTriggerTypeUI() {
var triggerType = document.getElementById('trigger_type').value;
document.getElementById('badge-trigger-section').style.display = (triggerType === 'badge') ? '' : 'none';
document.getElementById('attestation-condition-section').style.display = (triggerType === 'attestation-condition') ? '' : 'none';
}
function addConditionRow() {
var list = document.getElementById('conditions-list');
var row = document.createElement('div');
row.className = 'row mb-2 condition-row';
row.innerHTML = `
<div class="col">
<input type="text" class="form-control" name="condition_field" placeholder="Field">
</div>
<div class="col">
<input type="text" class="form-control" name="condition_value" placeholder="Value (comma for list)">
</div>
<div class="col-auto">
<button type="button" class="btn btn-danger btn-sm" onclick="removeConditionRow(this)">Remove</button>
</div>
`;
list.appendChild(row);
}
function removeConditionRow(btn) {
btn.closest('.condition-row').remove();
}
window.addEventListener('DOMContentLoaded', function() {
updateTriggerTypeUI();
});
</script>
{% endblock %}