ayb 0.1.12

ayb makes it easy to create, host, and share embedded databases like SQLite and DuckDB
Documentation
{% extends "base_content.html" %}

{% block title %}{{ entity }} - API Tokens{% endblock %}

{% block page_content %}
<div class="max-w-screen-xl mx-auto">
    <div class="breadcrumbs mb-4">
        <a href="/{{ entity }}" class="hover:underline">{{ entity }}</a> /
        <span class="font-semibold">API Tokens</span>
    </div>

    {% if tokens | length == 0 %}
    <p class="text-muted-foreground">No active API tokens found.</p>
    {% else %}
    <div class="overflow-x-auto">
    <table class="uk-table uk-table-striped uk-table-small">
        <thead>
            <tr>
                <th>Short token</th>
                <th>Scope</th>
                <th>Permission</th>
                <th>App</th>
                <th>Created</th>
                <th>Expires</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody id="tokens-table">
            {% for token in tokens %}
            <tr id="token-row-{{ token.short_token }}">
                <td><code class="text-sm">{{ token.short_token }}</code></td>
                <td>{{ token.scoped_database | default(value="(all databases)") }}</td>
                <td>{{ token.permission_level | default(value="(full access)") }}</td>
                <td>{{ token.app_name | default(value="") }}</td>
                <td>{{ token.created_at | default(value="") }}</td>
                <td>{{ token.expires_at | default(value="(never)") }}</td>
                <td>
                    <button
                        type="button"
                        class="uk-btn uk-btn-danger uk-btn-sm"
                        onclick="confirmRevokeToken('{{ token.short_token }}')">
                        Revoke
                    </button>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    </div>
    {% endif %}

    <!-- Revoke token confirmation modal -->
    <div id="revoke-token-modal" class="uk-flex-top" data-uk-modal>
        <div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical">
            <h2 class="uk-modal-title">Revoke token</h2>
            <p class="mt-1">Are you sure you want to revoke token <code id="revoke-token-id"></code>?</p>
            <p class="uk-text-muted text-sm mt-2">This token will no longer be able to access the API.</p>
            <p class="uk-text-right mt-4">
                <button class="uk-btn uk-btn-default uk-modal-close" type="button">Cancel</button>
                <button
                    class="uk-btn uk-btn-destructive"
                    id="confirm-revoke-btn"
                    type="button"
                    onclick="revokeToken()">
                    Revoke token
                </button>
            </p>
        </div>
    </div>

    <script>
        let revokeTokenShortToken = '';

        function confirmRevokeToken(shortToken) {
            revokeTokenShortToken = shortToken;
            document.getElementById('revoke-token-id').textContent = shortToken;
            UIkit.modal('#revoke-token-modal').show();
        }

        function revokeToken() {
            const shortToken = revokeTokenShortToken;
            const targetRow = document.getElementById('token-row-' + shortToken);

            fetch('/settings/tokens/' + shortToken, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            .then(response => {
                if (response.ok) {
                    return response.text();
                }
                throw new Error('Failed to revoke token');
            })
            .then(html => {
                // Replace the row with the success message
                targetRow.outerHTML = html;
                UIkit.modal('#revoke-token-modal').hide();
            })
            .catch(error => {
                console.error('Error revoking token:', error);
                UIkit.modal('#revoke-token-modal').hide();
            });
        }
    </script>
</div>
{% endblock %}