{% extends "meta.html" %}
{% block title %}
<title>~{{user.username}} - {{cfg("sr.ht", "site-name")}} meta</title>
{% endblock %}
{% block content %}
<div class="alert alert-danger">
<strong>Notice</strong>: This page contains private user information.
Remember your committment to protecting the privacy of the person listed
here and do not share any of this information with unauthorized
individuals. Don't fall for spear phishing — double check that you've
received an authentic support request before doing anything on the user's
behalf!
</div>
<h3>~{{user.username}}</h3>
<div class="row">
<section class="col-md-12">
<dl class="row">
<dt class="col-md-3">User ID</dt>
<dd class="col-md-9">{{user.id}}</dd>
<dt class="col-md-3">Email</dt>
<dd class="col-md-9">
<a href="mailto:{{user.email}}">{{user.email}}</a>
</dd>
<dt class="col-md-3">Registered</dt>
<dd class="col-md-9">{{user.created | date}}</dd>
<dt class="col-md-3">User type</dt>
<dd class="col-md-9">{{user.user_type.value}}</dd>
{% if user.user_type.value == "suspended" %}
<dt class="col-md-3">Suspension Notice</dt>
<dd class="col-md-9">{{user.suspension_notice}}</dd>
{% endif %}
{% if user.location %}
<dt class="col-md-3">Location</dt>
<dd class="col-md-9">{{user.location}}</dd>
{% endif %}
{% if user.url %}
<dt class="col-md-3">URL</dt>
<dd class="col-md-9">
<a
href="{{user.url}}"
target="_blank"
rel="me noopener noreferrer nofollow"
>{{user.url}}</a>
</dd>
{% endif %}
{% if cfg("meta.sr.ht::billing", "enabled") == "yes"
and user.stripe_customer %}
<dt class="col-md-3">Stripe customer</dt>
<dd class="col-md-9">
<a href="https://dashboard.stripe.com/customers/{{user.stripe_customer}}">
{{user.stripe_customer}}
</a>
</dd>
<dt class="col-md-3">Payment amount</dt>
<dd class="col-md-9">
${{"{:.2f}".format(user.payment_cents / 100)}}
</dd>
<dt class="col-md-3">Payment interval</dt>
<dd class="col-md-9">
{{user.payment_interval.value}}
</dd>
<dt class="col-md-3">Payment due</dt>
<dd class="col-md-9">{{user.payment_due | date}}</dd>
{% endif %}
</dl>
{% if user.bio %}
<blockquote>
{{user.bio | md}}
</blockquote>
{% endif %}
{% if reset_pending %}
<div class="alert alert-warning">
<a
href="{{url_for("auth.reset_GET", token=user.reset_hash)}}"
class="btn btn-link pull-right"
>reset link</a>
Password reset pending.
</div>
{% endif %}
<form
method="POST"
action="{{url_for("users.set_user_type", username=user.username)}}"
class="alert alert-info"
>
{{csrf_token()}}
<button
type="submit"
class="btn btn-primary btn-sm pull-right"
>
Update
</button>
<select
name="user_type"
class="form-control"
style="display: inline; width: inherit"
>
{% for type in [
"unconfirmed", "active_non_paying", "active_free", "active_paying",
"active_delinquent", "admin" ] %}
<option
value="{{type}}"
{% if user.user_type.value == type %}
selected
{% endif %}
>{{type}}</option>
{% endfor %}
{% if user.user_type.value == "suspended" %}
{# You can remove this here, but not set it #}
<option value="suspended" selected>suspended</option>
{% endif %}
</select>
</form>
{% if totp %}
<form
method="POST"
action="{{url_for("users.user_disable_totp", username=user.username)}}"
class="alert alert-warning"
>
{{csrf_token()}}
<button type="submit" class="btn btn-link pull-right">
Disable TOTP
</button>
This account has TOTP enabled.
</form>
{% endif %}
<form
method="POST"
action="{{url_for("users.user_delete_POST", username=user.username)}}"
class="alert alert-danger"
>
{{csrf_token()}}
Check both boxes to delete this account:
<button type="submit" class="btn btn-danger pull-right">
Delete account
{{icon('caret-right')}}
</button>
<input type="checkbox" id="safe-1" name="safe-1">
<label class="form-check-label" for="safe-1">
Confirm once
</label>
<input type="checkbox" id="safe-2" name="safe-2">
<label class="form-check-label" for="safe-2">
Confirm twice
</label>
</form>
</section>
</div>
<div class="row">
<form
class="col-md-12"
action="{{url_for('.user_add_note', username=user.username)}}"
method="POST"
>
<h3>User notes</h3>
<div class="event-list">
{% for note in user.notes %}
<div class="event">
{{note.note}}
<span class="text-muted">{{note.created | date}}</span>
</div>
{% endfor %}
</div>
<div class="form-group">
<textarea
id="notes"
name="notes"
class="form-control {{valid.cls('notes')}}"
rows="3"
>{{notes if notes else ""}}</textarea>
{{valid.summary('notes')}}
</div>
{{csrf_token()}}
<button type="submit" class="btn btn-primary pull-right">
Add note
{{icon('caret-right')}}
</button>
</form>
</div>
<div class="row">
<form
class="col-md-12"
method="POST"
action="{{url_for("users.user_suspend", username=user.username)}}"
>
<h3>Suspend account</h3>
{{csrf_token()}}
<div class="form-group">
<input
type="text"
placeholder="Suspension reason (shown to user)"
class="form-control"
name="reason" />
</div>
<button type="submit" class="btn btn-danger pull-right">
Suspend user
{{icon('caret-right')}}
</button>
</form>
</div>
<div class="row">
<div class="col-md-12">
{% if any(user.ssh_keys) %}
<h3>SSH keys</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Fingerprint</th>
<th>Authorized</th>
<th>Last Used</th>
</tr>
</thead>
<tbody>
{% for key in user.ssh_keys %}
<tr>
<td>{{key.comment}}</td>
<td>
<details>
<summary>{{key.fingerprint}}</summary>
<pre style="max-width: 600px">{{key.key}}</pre>
</details>
</td>
<td>{{key.created|date}}</td>
<td>{{key.last_used|date}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if any(user.pgp_keys) %}
<h3>PGP keys</h3>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Fingerprint</th>
<th>Authorized</th>
</tr>
</thead>
<tbody>
{% for key in user.pgp_keys %}
<tr>
<td>{{key.id}}</td>
<td>
<details>
<summary>{{key.fingerprint_hex}}</summary>
<pre style="max-width: 600px">{{key.key}}</pre>
</details>
</td>
<td>{{key.created|date}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if user.confirmation_hash %}
<div class="alert alert-warning">
<a
href="{{url_for("auth.confirm_account", token=user.confirmation_hash)}}"
class="btn btn-link pull-right"
>confirmation link</a>
This account is pending confirmation.
</div>
{% endif %}
</div>
</div>
<div class="row">
<form
class="col-md-12"
method="POST"
action="{{url_for("users.user_invoice", username=user.username)}}"
>
<h3>Issue account credit</h3>
{{csrf_token()}}
<div class="row">
<div class="form-group col-md-6">
<label for="amount">Amount (in dollars)</label>
<input
type="number"
placeholder="Amount"
class="form-control"
id="amount"
name="amount"
value="20" />
</div>
<div class="form-group col-md-6">
<label for="comment">Valid thru</label>
<input
type="date"
class="form-control"
name="valid_thru"
value="{{one_year.strftime("%Y-%m-%d")}}" />
</div>
</div>
<div class="form-group">
<label for="source">Source ("paid with..." in billing UI)</label>
<input
type="text"
placeholder="e.g. 'PayPal'"
class="form-control"
name="source" />
</div>
<button type="submit" class="btn btn-primary pull-right">
Issue invoice
{{icon('caret-right')}}
</button>
</form>
</div>
{% if user.user_type.value == "active_paying" %}
<div class="row">
<form
class="col-md-12"
action="{{url_for('.user_transfer_billing', username=user.username)}}"
method="POST"
>
<h3>Transfer billing information</h3>
<div class="form-group">
<label for="target">New user</label>
<input
type="text"
id="target"
name="target"
class="form-control {{valid.cls('target')}}"
value="{{target or "" }}" />
{{valid.summary('target')}}
</div>
{{csrf_token()}}
<button type="submit" class="btn btn-primary pull-right">
Transfer billing
{{icon('caret-right')}}
</button>
</form>
</div>
{% endif %}
<div class="row">
<section class="col-md-12">
<h3>Audit Log</h3>
<table class="table">
<thead>
<tr>
<th>IP Address</th>
<th>Host</th>
<th>Details</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for log in audit_log %}
<tr>
<td>{{log.ip_address}}</td>
<td>{{rdns.get(log.ip_address.exploded, "unknown")}}</td>
<td>{{log.details or log.event_type}}</td>
<td>{{log.created | date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</div>
<div class="row">
<div class="col-md-12 event-list">
<section>
<h3>Personal Access Tokens</h3>
<table class="table">
<thead>
<tr>
<th>Comment</th>
<th>Issued</th>
<th>Expires</th>
<th></th>
</tr>
</thead>
<tbody>
{% for token in personal_tokens %}
<tr>
<td>{{ token.comment }}</td>
<td>{{ token.issued | date }}</td>
<td>{{ token.expires | date }}</td>
<td style="width: 6rem">
<a
href="{{url_for('oauth2.personal_token_revoke_GET',
token_id=token.id)}}"
class="btn btn-danger btn-fill"
>Revoke</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
<section>
<h3>Authorized Clients</h3>
<table class="table">
<thead>
<tr>
<th>Service</th>
<th>Operator</th>
<th>Issued</th>
<th>Expires</th>
<th></th>
</tr>
</thead>
<tbody>
{% for grant in oauth_grants %}
<tr>
<td>
{# lol this hack is awful #}
<a
href="{{grant.client.url}}"
rel="noopener"
>{{ grant.client.name }}</a>
<a
href="{{grant.client.url}}"
rel="noopener"
>{{icon('external-link-alt')}}</a>
</td>
<td>{{grant.client.owner.canonicalName}}</td>
<td>{{grant.issued | date}}</td>
<td>{{grant.expires | date}}</td>
<td style="width: 6rem">
<a
href="{{url_for("oauth2.bearer_token_revoke_GET",
token_hash=grant.tokenHash)}}"
class="btn btn-danger btn-fill"
>Revoke</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
<section>
<h3>Registered Clients</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Client ID</th>
<th></th>
</tr>
</thead>
<tbody>
{% for client in oauth_clients %}
<tr>
<td>
{# lol this hack is awful #}
<a
href="{{client.url}}"
rel="noopener"
>{{ client.name }}</a>
<a
href="{{client.url}}"
rel="noopener"
>{{icon('external-link-alt')}}</a>
</td>
<td>{{ client.uuid }}</td>
<td style="width: 6rem">
<a
href="{{url_for('oauth2.manage_client_GET', uuid=client.uuid)}}"
class="btn btn-default btn-fill"
>Manage {{icon('caret-right')}}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
<section>
<h3>Invoices</h3>
<div class="event-list">
{% for invoice in invoices %}
<div class="event invoice">
<h4>
<small class="text-success" style="margin-left: 0">
{{icon('check')}}
</small>
${{"{:.2f}".format(invoice.cents/100)}}
<small>
with {{invoice.source}}
</small>
<small>
<a
class="pull-right"
href="{{url_for("billing.invoice_GET", invoice_id=invoice.id)}}"
>Export as PDF</a>
</small>
</h4>
<p>
Paid {{invoice.created | date}}<br />
Valid for service until {{invoice.valid_thru | date}}
{% if invoice.comment %}
<br />
{{invoice.comment}}
{% endif %}
</p>
</div>
{% endfor %}
</div>
</section>
</div>
<form
class="col-md-8"
action="{{url_for("users.user_impersonate_POST", username=user.username)}}"
method="POST"
>
{{csrf_token()}}
<h3>Impersonate user</h3>
<div class="form-group">
<label for="reason">Reason</label>
<input
type="text"
class="form-control {{valid.cls('reason')}}"
id="reason"
name="reason"
value="{{reason if reason else ""}}" />
{{valid.summary('reason')}}
</div>
<div class="alert alert-danger">
This will send a security notification to the user and the admin security
mailing list. You must have the user's permission to use this feature.
</div>
<button type="submit" class="btn btn-primary">
Impersonate this user
{{icon('caret-right')}}
</button>
</form>
</div>
{% endblock %}