{% extends "master.html" %}
{% from "_formhelper.html" import render_bootstrap_field %}
{% from "_projectstring.html" import projectstring, projecticon %}
{% block title %}{{ user.user }}'s settings{% endblock %}
{% set tag = "users"%}
{% macro render_email(email, form, validated=True) %}
<div class="list-group-item {% if not validated %}disabled{% endif %}">
<span class="fa fa-envelope text-muted"></span> {{ email.email }}
{% if validated %}
<form class="float-right" method="POST"
action="{{ url_for('ui_ns.remove_user_email') }}">
<input type="hidden" value="{{ email.email }}" name="email" />
{{ form.csrf_token }}
<button title="Remove email" data-email="{{ email.email }}"
class="btn btn btn-outline-danger delete-email-btn">
<i class="fa fa-trash fa-fw"></i>
</button>
</form>
{% if email.email == user.default_email %}
<div class="btn button-outline-light text-warning float-right mr-1">
<span class="fa fa-star" title="default email address" data-toggle="tooltip"></span>
</div>
{% else %}
<form class="inline" method="POST"
action="{{ url_for('ui_ns.set_default_email') }}" id="default_mail">
<input type="hidden" value="{{ email.email }}" name="email" />
{{ form.csrf_token }}
<a class="float-right p-r-1 btn btn-outline-warning border-0 text-secondary mr-1 pointer submit-btn"
data-form-id="email" title="Set as default email address">
<span class="fa fa-star" data-toggle="tooltip"></span>
</a>
</form>
{% endif %}
{% else %}
<div class="float-right">
<small>pending verification via email </small>
<form class="inline" method="POST"
action="{{ url_for('ui_ns.reconfirm_email') }}" id="reconfirm_mail">
<input type="hidden" value="{{ email.email }}" name="email" />
{{ form.csrf_token }}
<button data-form-id="reconfirm_mail"
title="Resend validation email" class="btn btn btn-outline-primary submit-btn">
<span class="fa fa-retweet fa-fw"></span>
</button>
</form>
</div>
{% endif %}
</div>
{% endmacro %}
{% block content %}
<div class="container p-t-3">
<div class="row">
<div class="col">
<nav>
<div class="nav nav-tabs nav-sidetabs flex-column" id="nav-tab" role="tablist">
<h5 class="pl-2 font-weight-bold text-muted">User Settings</h5>
<a class="nav-item nav-link active" id="nav-basic-tab" data-toggle="tab" href="#nav-basic" role="tab" aria-controls="nav-basic" aria-selected="true">Profile</a>
<a class="nav-item nav-link" id="nav-email-tab" data-toggle="tab" href="#nav-email" role="tab" aria-controls="nav-email" aria-selected="true">Email Addresses</a>
<a class="nav-item nav-link" id="nav-api-tab" data-toggle="tab" href="#nav-api" role="tab" aria-controls="nav-api" aria-selected="true">API Keys</a>
{% if config.get('LOCAL_SSH_KEY', True) %}
<a class="nav-item nav-link" id="nav-ssh-tab" data-toggle="tab" href="#nav-ssh" role="tab" aria-controls="nav-ssh" aria-selected="true">SSH Keys</a>
{% endif %}
<a class="nav-item nav-link" id="nav-user-tab" data-toggle="tab" href="#nav-user" role="tab" aria-controls="nav-user" aria-selected="true">Preferences</a>
<a class="nav-item nav-link" id="nav-force-tab" data-toggle="tab" href="#nav-force" role="tab" aria-controls="nav-force" aria-selected="true">Force Logout</a>
</div>
</nav>
</div>
<div class="col-9">
<div class="tab-content mt-4" id="nav-tabContent">
<div class="tab-pane fade active show" id="nav-basic" role="tabpanel" aria-labelledby="nav-basic-tab">
<h3 class="font-weight-bold mb-3">
Basic Information
{% if config.get('PAGURE_AUTH')=='local' %}
<a class="btn btn-sm btn-outline-primary float-right" href="{{ url_for('ui_ns.change_password', username=g.fas_user.username) }}">Change password</a>
{% endif %}
</h3>
<div class="row">
<div class="col-xs-auto ml-4">
<fieldset class="form-group text-center">
<div>
<div class="p-2 mt-2 bg-light border border-secondary"> {{ g.fas_user.username | avatar(80) | safe }} </div>
<a class="btn btn-outline-primary btn-sm mt-1" href="https://www.libravatar.org/account/login/">
Change Avatar </a>
</div>
</fieldset>
</div>
<div class="col ml-4">
<fieldset class="form-group">
<label for="description"><strong>Username</strong></label>
<input class="form-control" type="text" disabled value="{{ user.user }}"/>
</fieldset>
<fieldset class="form-group">
<label for="description"><strong>Full Name</strong></label>
<input class="form-control" type="text" disabled value="{{ user.fullname }}"/>
</fieldset>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-email" role="tabpanel" aria-labelledby="nav-email-tab">
<h3 class="font-weight-bold mb-3">
Email Addresses
<a class="btn btn-outline-primary btn-sm float-right" href="{{
url_for('ui_ns.add_user_email') }}">
Add Email
</a>
</h3>
<div class="row">
<div class="col">
<div class="list-group">
{% for email in user.emails %}
{{ render_email(email, form) }}
{% endfor %}
{% for email in user.emails_pending %}
{{ render_email(email, form, validated=False) }}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-api" role="tabpanel" aria-labelledby="nav-api-tab">
<h3 class="font-weight-bold mb-3">
API Keys
<a href="{{ url_for('ui_ns.add_api_user_token') }}" method="post" class="icon float-right">
<button class="btn btn-sm btn-outline-primary" type="submit"
title="Generate a new API token">
Create new API Key
</button>
</a>
</h3>
<div class="row">
<div class="col">
<p>
API keys are tokens used to authenticate you on pagure. They can also
be used to grant access to 3rd party application to behave on all
{{projectstring(plural=True)}} in your name.
</p>
<p>
These are your personal tokens; they are not visible to others.
</p>
<p>
These keys are valid for <span class="strong">60</span> days.
</p>
<p>
These keys are private, make sure to store in a safe place and
do not share it.
</p>
{% if user.tokens %}
{% for token in user.tokens %}
{% if not token.project %}
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend font-weight-bold">
<span class="input-group-text">
<span class="fa fa-key fa-fw"></span>
{{ token.description or '' }}
</span>
</div>
<div class="input-group-prepend">
<span class="input-group-text">
{% for acl in token.acls_list %}
{% if acl == 'create_project' %}
<span title="This key has ACLs to create new {{projectstring(plural=True)}}"><i class="fa fa-fw fa-plus text-muted"></i></span>
{% elif acl == 'fork_project' %}
<span title="This key has ACLs to fork {{projectstring(plural=True)}}"><i class="fa fa-fw fa-code-fork text-muted"></i></span>
{% elif acl == 'modify_project' %}
<span title="This key has ACLs to modify {{projectstring(plural=True)}}"><i class="fa fa-fw fa-pencil-square-o text-muted"></i></span>
{% endif %}
{% endfor %}
</span>
</div>
<input class="form-control bg-white font-monospace"
type="text" value="{{ token.id }}" readonly>
{% if token.expired %}
<span class="input-group-prepend">
<small class="font-weight-bold text-danger input-group-text">Expired on {{ token.expiration.date() }}</small>
</span>
{% else %}
<span class="input-group-prepend">
<small class="font-weight-bold text-success input-group-text">Active until {{ token.expiration.date() }}</small>
</span>
{% endif %}
{% if not token.expired %}
<form action="{{ url_for(
'ui_ns.revoke_api_user_token', token_id=token.id) }}"
method="post" class="icon">
<button class="btn btn-outline-danger remote-token-btn" type="submit"
title="Revoke token">
<i class="fa fa-trash"></i>
</button>
{{ form.csrf_token }}
</form>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
{% if config.get('LOCAL_SSH_KEY', True) %}
<div class="tab-pane fade" id="nav-ssh" role="tabpanel" aria-labelledby="nav-ssh-tab">
<h3 class="font-weight-bold mb-3">
SSH Keys
<a class="btn btn-outline-primary btn-sm float-right ssh_key_btn ssh_key_block pointer">
Add SSH key
</a>
</h3>
<div class="row">
<div class="col">
<p>Below are your SSH keys.</p>
{% for key in user.sshkeys %}
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><span class="fa fa-key"></span></span>
</div>
<input class="form-control bg-white font-monospace" readonly
type="text" value="{{ key.ssh_short_key }}"/>
<form class="pull-xs-right" method="POST"
action="{{ url_for(
'ui_ns.remove_user_sshkey',
keyid=key.id) }}">
<button title="Remove SSH key"
class="btn btn-outline-danger delete-sshkey-btn">
<i class="fa fa-trash"></i>
</button>
{{ form.csrf_token }}
</form>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="row justify-content-around ssh_key_block hidden">
<div class="col">
<div class="card mt-5">
<div class="card-header">
<strong>Add SSH key</strong>
</div>
<div class="card-body">
<form action="{{ url_for('ui_ns.add_user_sshkey') }}" method="post">
<fieldset class="form-group">
<label for="ssh_key"><strong>SSH key</strong></label>
<textarea class="form-control" name="ssh_key" id="ssh_key"></textarea>
</fieldset>
<p class="buttons indent">
<input type="button" value="Cancel" class="btn btn-secondary ssh_key_btn">
<input type="submit" class="btn btn-primary" value="Add">
{{ form.csrf_token }}
</p>
</form>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="tab-pane fade" id="nav-user" role="tabpanel" aria-labelledby="nav-ssh-tab">
<h3 class="font-weight-bold mb-3">
User Settings
</h3>
<div class="row">
<div class="col">
<form action="{{ url_for('ui_ns.update_user_settings') }}" method="post">
<div class="list-group">
{% for key in user.settings | sort %}
{% if user.settings[key] in [True, False, 'y'] %}
<div class="list-group-item">
<label class="custom-input custom-checkbox">
<input id="{{ key }}" type="checkbox" value="y" name="{{ key }}" {%
if user.settings[key] -%}checked=""{%- endif -%}/>
<span class="c-indicator"></span>
Activate {{ key | replace('_', ' ') }}
</label>
</div>
{% else %}
<div class="list-group-item">
<label for="{{ key }}">Activate {{ key | replace('_', ' ') }} :</label>
<input width="4em" class="form-control" id="{{ key }}" type="text" {%
if user.settings[key] %}value="{{ user.settings[key] }}"{%
endif %} name="{{ key }}" />
</div>
{% endif %}
{% endfor %}
</div>
<p class="mt-3">
<input type="submit" class="btn btn-primary" value="Update">
{{ form.csrf_token }}
</p>
</form>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-force" role="tabpanel" aria-labelledby="nav-force-tab">
<h3 class="font-weight-bold mb-3">
Force Logout
</h3>
<div class="row">
<div class="col">
<p>
Forcefully log out from every current open session.
</p>
<form action="{{ url_for('ui_ns.force_logout') }}" method="post">
<input type="submit" class="btn btn-outline-danger"
value="Log out all currently active sessions">
{{ form.csrf_token }}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block jscripts %}
{{ super() }}
<script type="text/javascript" nonce="{{ g.nonce }}">
$(document).ready(function() {
$('.submit-btn').click(function() {
var _form_name = $(this).attr('data-form-id');
$('#' + _form-id).submit();
});
$('.remove-token-btn').click(function() {
return confirm('Are you sure to revoke this token ?'
+ '\nThis will break all application using it and '
+ 'cannot be un-done.');
})
$('.delete-email-btn').click(function() {
return confirm('Do you really want to remove the email: ' + $(this).attr('data-email') + '?');
})
$('.delete-sshkey-btn').click(function() {
return confirm('You sure you want to remove this SSH key?');
})
$('#nav-tab a.nav-link').on('shown.bs.tab', function (e) {
window.location.hash = e.target.hash+'-tab';
window.scrollTo(0,0);
});
if (!window.location.hash){
window.location.hash = "#nav-basic-tab"
}
window.onhashchange = function () {
$(window.location.hash).tab('show');
}
const _anchor = window.location.hash;
console.log(_anchor);
$(_anchor).tab('show');
window.scrollTo(0,0);
$(".ssh_key_btn").click(function() {
$(".ssh_key_block").toggle();
});
});
</script>
{% endblock %}