315 lines
15 KiB
HTML
315 lines
15 KiB
HTML
{#
|
|
|
|
DATA FIELDS
|
|
current_data: dict
|
|
schema: BaseModel.model_json_schema()
|
|
system_fields: Optional[list] # An optional list of fields to disable when "system"
|
|
# is not part of a user's ACL
|
|
root_key: Optional[str] # A string to encapsulate a name in,
|
|
# i.e. a root_key "profile" for a field "email" becomes "profile.email"
|
|
|
|
#}
|
|
|
|
{% for k, v in schema.properties.items() if k not in without %}
|
|
{% if v.type in ["text", "email", "number"] %}
|
|
{% set readonly = True if "readonly" in v.input_extra else False %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }} {{ "🚫" if readonly }}</label>
|
|
<input {{ v.input_extra|safe }} id="{{ v.form_id }}"
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
type="{{ v.type }}"
|
|
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}">
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
{% elif v.type in ["date", "datetime-local"] %}
|
|
|
|
{% set readonly = True if "readonly" in v.input_extra else False %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }} {{ "🚫" if readonly }}</label>
|
|
<input {{ v.input_extra|safe }} id="{{ v.form_id }}"
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
type="{{ v.type }}"
|
|
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}">
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
{% elif v.type == "select:multi" or v.type == "select" %}
|
|
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<select {{ v.input_extra|safe }}
|
|
{% if v.type == "select:multi" %}
|
|
multiple
|
|
size="5"
|
|
{% endif %}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}">
|
|
{% for option in v.options %}
|
|
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k] or option["value"] == "" and not current_data[k] }}>{{ option["name"] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
{% elif v.type == "tresor" %}
|
|
|
|
{% if request.path == "/profile/" %}
|
|
<details name="tresor">
|
|
<summary role="button">{{ v.title }}</summary>
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %} class="tresor">
|
|
<input id="{{ v.form_id }}" type="hidden" {{ v.input_extra|safe }}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
value="{% if current_data[k] %}{{ current_data[k] }}{% endif %}" />
|
|
{% if not current_data[k] %}
|
|
<legend>Setup tresor</legend>
|
|
<input form="_ignore" id="{{ v.form_id }}-password" name="{{ v.form_id }}-password" type="password" {{ v.input_extra|safe }} />
|
|
<small>Password</small>
|
|
<input form="_ignore" id="{{ v.form_id }}-password2" name="{{ v.form_id }}-password2" type="password" {{ v.input_extra|safe }} />
|
|
<small>Confirm password</small>
|
|
<a role="button" href="#" _="on click halt the event
|
|
if not value of #{{ v.form_id }}-password
|
|
trigger notification(level: 'validationError', message: 'Missing password', duration: 3000, locations: ['{{ v.form_id }}-password'])
|
|
exit
|
|
end
|
|
if value of #{{ v.form_id }}-password != value of #{{ v.form_id }}-password2
|
|
trigger notification(level: 'validationError', message: 'Passwords do not match', duration: 3000, locations: ['{{ v.form_id }}-password', '{{ v.form_id }}-password2'])
|
|
exit
|
|
end
|
|
call VaultSetupUserCryptoAndSend(value of #{{ v.form_id }}-password)
|
|
set value of #{{ v.form_id }} to (result as JSON)
|
|
call window.vault.lock()
|
|
add @disabled to <input[type=password]/> in closest .tresor
|
|
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
|
|
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">
|
|
Setup encryption
|
|
</a>
|
|
{% else %}
|
|
<legend>Change tresor password</legend>
|
|
<input form="_ignore" id="old-{{ v.form_id }}" name="old-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
|
|
<small>Current password</small>
|
|
<input form="_ignore" id="new-{{ v.form_id }}" name="new-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
|
|
<small>New password</small>
|
|
<input form="_ignore" id="new2-{{ v.form_id }}" name="new2-{{ v.form_id }}" type="password" {{ v.input_extra|safe }} />
|
|
<small>Confirm new password</small>
|
|
<a role="button" href="#" _="install confirmButton on confirmedButton halt the event
|
|
if not value of #old-{{ v.form_id }}
|
|
trigger notification(level: 'validationError', message: 'Missing current password', duration: 3000, locations: ['old-{{ v.form_id }}'])
|
|
exit
|
|
end
|
|
if not value of #new-{{ v.form_id }}
|
|
trigger notification(level: 'validationError', message: 'Missing new password', duration: 3000, locations: ['new-{{ v.form_id }}'])
|
|
exit
|
|
end
|
|
if value of #new-{{ v.form_id }} != value of #new2-{{ v.form_id }}
|
|
trigger notification(level: 'validationError', message: 'Passwords do not match', duration: 3000, locations: ['new-{{ v.form_id }}', 'new2-{{ v.form_id }}'])
|
|
exit
|
|
end
|
|
set previousLock to window.vault.isUnlocked()
|
|
call JSON.parse(value of #{{ v.form_id }}) set keyData to the result
|
|
call VaultChangePassword(value of #old-{{ v.form_id }}, value of #new-{{ v.form_id }}, keyData)
|
|
call window.vault.exportPayload()
|
|
set value of #{{ v.form_id }} to (result as JSON)
|
|
add @disabled to closest .tresor
|
|
if not previousLock call window.vault.lock() end
|
|
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
|
|
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">
|
|
Change password
|
|
</a>
|
|
{% endif %}
|
|
</fieldset>
|
|
</details>
|
|
{% endif %}
|
|
|
|
{% elif v.type == "datalist" %}
|
|
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<input list="{{ v.form_id }}-datalist"
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}"
|
|
value="{% if current_data[k] == None %}{{ v.default }}{% else %}{{ current_data[k] }}{% endif %}" {{ v.input_extra|safe }}>
|
|
<datalist
|
|
id="{{ v.form_id }}-datalist">
|
|
{% for option in v.options %}
|
|
<option value="{{ option }}">
|
|
{% endfor %}
|
|
</datalist>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
{% elif (v.type == "users:multi" or v.type == "users") and "system" in session["acl"] %}
|
|
|
|
{% if not request.form_options.users or request.form_options.users == [] %}
|
|
<p>No users found</p>
|
|
{% else %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<select {{ v.input_extra|safe }}
|
|
{% if v.type == "users:multi" %}
|
|
multiple
|
|
size="5"
|
|
{% endif %}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}">
|
|
{% for option in request.form_options.users %}
|
|
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k] }}>{{ option["name"] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
{% endif %}
|
|
|
|
{% elif v.type == "emailusers:multi" or v.type == "emailusers" %}
|
|
{% if request.form_options.emailusers == [] %}
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<p><mark>No email users available</mark></p>
|
|
{% else %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<select {{ v.input_extra|safe }}
|
|
{% if v.type == "emailusers:multi" %}
|
|
multiple
|
|
size="5"
|
|
{% endif %}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}">
|
|
{% for option in request.form_options.emailusers %}
|
|
<option value="{{ option["value"] }}" {{ "selected" if option["value"] in current_data[k]|map(attribute="id")|list }}>{{ option["name"] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
{% endif %}
|
|
|
|
{% elif v.type == "list:text" or v.type == "list:number" %}
|
|
|
|
{% set readonly = True if "readonly" in v.input_extra else False %}
|
|
<template id="list:item">
|
|
<div>
|
|
<input {{ v.input_extra|safe }}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
type="{{ "text" if v.type == "list:text" else "number" }}"
|
|
placeholder="New element">
|
|
<small><a href="#" hx-on:click="event.preventDefault();this.closest('div').remove()">Remove</a></small>
|
|
</div>
|
|
</template>
|
|
<fieldset data-loading-disable id="{{ v.form_id }}" _="on click from .add-list-item in me halt the event then render #list:item then put the result at the end of me end">
|
|
<legend>{{ v.title }} <a {{ "hidden" if readonly }} href="#" class="add-list-item">Add</a> {{ "🚫" if readonly }}</legend>
|
|
{% for list_value in current_data[k] or v.default %}
|
|
<div>
|
|
<input {{ v.input_extra|safe }}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
type="{{ "text" if v.type == "list:text" else "number" }}"
|
|
value="{{ list_value }}">
|
|
<small {{ "hidden" if readonly }}><a href="#" hx-on:click="event.preventDefault();this.closest('div').remove()">Remove</a></small>
|
|
</div>
|
|
{% endfor %}
|
|
</fieldset>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
|
|
{% elif v.type == "radio" %}
|
|
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<legend for="{{ v.form_id }}">{{ v.title }}</legend>
|
|
{% for radio_value in v.enum %}
|
|
<label>
|
|
<input {{ v.input_extra|safe }}
|
|
id="{{ v.form_id }}"
|
|
type="radio"
|
|
value="{{ radio_value }}"
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
{{ "checked" if (current_data[k] != None and current_data[k] == radio_value) or (current_data[k] == None and v.default == radio_value) }} />
|
|
{{ radio_value|capitalize }}
|
|
</label>
|
|
{% endfor %}
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
{% elif v.type == "keypair" %}
|
|
|
|
{% if not request.form_options.keypairs or request.form_options.keypairs == [] %}
|
|
<p>No key pairs available</p>
|
|
{% else %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field keypair" disabled{% endif %} class="keypair">
|
|
<legend>{{ v.title }}</legend>
|
|
<select {{ v.input_extra|safe }}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}"
|
|
_="
|
|
on change or load
|
|
set keypairId to (value of <option:checked/> in me) as String
|
|
put '' into #dns-data-{{ v.form_id }}
|
|
if keypairId
|
|
add @disabled to me
|
|
put '⌛' into #dns-data-{{ v.form_id }}
|
|
getJsonUrlAsObject('/objects/keypairs/' + keypairId)
|
|
put result.details.dns_formatted into #dns-data-{{ v.form_id }}
|
|
end
|
|
catch e
|
|
put '⛔' into #dns-data-{{ v.form_id }}
|
|
finally
|
|
remove @disabled from me
|
|
trigger validate on #dns-data-{{ v.form_id }}
|
|
end">
|
|
<option value="" {{ "selected" if current_data[k] == "" }}>-- None --</option>
|
|
|
|
{% for option in request.form_options.keypairs %}
|
|
<option value="{{ option["value"] }}" {{ "selected" if option["value"] == current_data[k].id }}>{{ option["name"] }}</option>
|
|
{% endfor %}
|
|
|
|
</select>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
<div>
|
|
<small><i>The required DNS TXT record's value for your convenience</i> (<span class="color-blue-200 pointer" _="on click trigger change on previous <option:checked/>">force reload</span>)</small>
|
|
<textarea rows="8" class="dns-data" readonly id="dns-data-{{ v.form_id }}" _="
|
|
on validate add @hidden to closest <div/> if my value is empty else remove @hidden from closest <div/> end end
|
|
on click call my.setSelectionRange(0, -1) end">
|
|
{{- "" -}}
|
|
</textarea>
|
|
</div>
|
|
{% endif %}
|
|
</fieldset>
|
|
{% endif %}
|
|
|
|
{% elif v.type == "domain" %}
|
|
|
|
{% if request.form_options.domains == [] %}
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<p><mark>No domain available</mark></p>
|
|
{% else %}
|
|
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %}>
|
|
<label for="{{ v.form_id }}">{{ v.title }}</label>
|
|
<select {{ v.input_extra|safe }}
|
|
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
|
|
id="{{ v.form_id }}">
|
|
{% for option in request.form_options.domains %}
|
|
<option value="{{ option["value"] }}" {{ "selected" if option["value"] == current_data[k].id }}>{{ option["name"] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if v.description %}
|
|
<small>{{ v.description|safe }}</small>
|
|
{% endif %}
|
|
</fieldset>
|
|
{% endif %}
|
|
|
|
{% endif %}
|
|
{% endfor %}
|