mockapi/templates/admin/oauth/client_form.html
2026-03-16 05:47:01 +00:00

140 lines
No EOL
7.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}{{ action }} OAuth Client - Mock API Admin{% endblock %}
{% block content %}
<div class="content-header">
<h1><i class="bi bi-pencil-square"></i> {{ action }} OAuth Client</h1>
<p class="lead">Configure an OAuth 2.0 client registration.</p>
</div>
{% if error %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ error }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-body">
<form method="post" action="{{ form_action }}" id="client-form">
{% if client and client.id %}
<input type="hidden" name="id" value="{{ client.id }}">
{% endif %}
<div class="mb-3">
<label for="client_name" class="form-label">Client Name <span class="text-danger">*</span></label>
<input type="text" class="form-control {% if errors and errors.client_name %}is-invalid{% endif %}" id="client_name" name="client_name" value="{{ client.name if client else '' }}" placeholder="My API Client" required>
<div class="invalid-feedback">
{{ errors.client_name if errors and errors.client_name else 'Client name is required.' }}
</div>
<div class="form-text">
Human-readable name for this client.
</div>
</div>
<div class="mb-3">
<label for="redirect_uris" class="form-label">Redirect URIs <span class="text-danger">*</span></label>
<textarea class="form-control {% if errors and errors.redirect_uris %}is-invalid{% endif %}" id="redirect_uris" name="redirect_uris" rows="3" required>{{ client.redirect_uris | join(', ') if client else '' }}</textarea>
<div class="invalid-feedback">
{{ errors.redirect_uris if errors and errors.redirect_uris else 'Enter one or more redirect URIs separated by commas.' }}
</div>
<div class="form-text">
Comma-separated list of allowed redirect URIs (must be http:// or https://). Example: <code>https://myapp.com/callback, https://localhost:3000/callback</code>.
</div>
</div>
<div class="mb-3">
<label for="grant_types" class="form-label">Grant Types <span class="text-danger">*</span></label>
<textarea class="form-control {% if errors and errors.grant_types %}is-invalid{% endif %}" id="grant_types" name="grant_types" rows="2" required>{{ client.grant_types | join(', ') if client else 'authorization_code,client_credentials,refresh_token' }}</textarea>
<div class="invalid-feedback">
{{ errors.grant_types if errors and errors.grant_types else 'Enter allowed grant types separated by commas.' }}
</div>
<div class="form-text">
Comma-separated list of OAuth 2.0 grant types. Allowed values: <code>authorization_code</code>, <code>client_credentials</code>, <code>password</code>, <code>refresh_token</code>.
</div>
</div>
<div class="mb-3">
<label for="scopes" class="form-label">Scopes</label>
<textarea class="form-control {% if errors and errors.scopes %}is-invalid{% endif %}" id="scopes" name="scopes" rows="2">{{ client.scopes | join(', ') if client else 'read,write' }}</textarea>
<div class="invalid-feedback">
{{ errors.scopes if errors and errors.scopes else 'Enter allowed scopes separated by commas.' }}
</div>
<div class="form-text">
Comma-separated list of OAuth scopes that this client can request. Example: <code>read,write,admin</code>.
</div>
</div>
<div class="mb-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="is_active" name="is_active" {% if client and client.is_active %}checked{% endif %}>
<label class="form-check-label" for="is_active">Client is active</label>
</div>
<div class="form-text">
Inactive clients cannot authenticate or obtain tokens.
</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="/admin/oauth/clients" class="btn btn-outline-secondary me-md-2">Cancel</a>
<button type="submit" class="btn btn-primary">Save Client</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0"><i class="bi bi-info-circle"></i> Help</h5>
</div>
<div class="card-body">
<h6>Client Credentials</h6>
<p>Client ID and secret will be generated automatically upon creation. The secret will be shown only once store it securely.</p>
<h6>Redirect URIs</h6>
<p>Must be absolute URIs with scheme http:// or https://. The redirect URI used in authorization requests must match exactly.</p>
<h6>Grant Types</h6>
<ul class="small">
<li><strong>authorization_code</strong>: For web server applications.</li>
<li><strong>client_credentials</strong>: For machinetomachine authentication.</li>
<li><strong>password</strong>: For trusted firstparty clients (discouraged).</li>
<li><strong>refresh_token</strong>: Allows obtaining new access tokens.</li>
</ul>
<h6>Security</h6>
<p>Client secrets are hashed using bcrypt before storage. Never expose secrets in logs or clientside code.</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script>
// Simple validation for comma-separated lists
function validateList(textareaId) {
const textarea = document.getElementById(textareaId);
if (textarea.value.trim() === '') {
textarea.classList.add('is-invalid');
return false;
}
textarea.classList.remove('is-invalid');
return true;
}
document.getElementById('redirect_uris')?.addEventListener('blur', () => validateList('redirect_uris'));
document.getElementById('grant_types')?.addEventListener('blur', () => validateList('grant_types'));
document.getElementById('client-form')?.addEventListener('submit', function(e) {
let valid = true;
if (!validateList('redirect_uris')) valid = false;
if (!validateList('grant_types')) valid = false;
if (!valid) e.preventDefault();
});
</script>
{% endblock %}