Move auth tokens to dedicated page

This commit is contained in:
Alice Gaudon 2021-03-29 12:55:20 +02:00
parent a5729af3c1
commit 0dfae21005
3 changed files with 65 additions and 44 deletions

View File

@ -3,13 +3,25 @@ import {RequireAuthMiddleware} from "swaf/auth/AuthComponent";
import {Request, Response} from "express"; import {Request, Response} from "express";
import AuthToken from "../models/AuthToken"; import AuthToken from "../models/AuthToken";
import {BadRequestError, ForbiddenHttpError, NotFoundHttpError} from "swaf/HttpError"; import {BadRequestError, ForbiddenHttpError, NotFoundHttpError} from "swaf/HttpError";
import config from "config";
export default class AuthTokenController extends Controller { export default class AuthTokenController extends Controller {
public routes(): void { public routes(): void {
this.get('/auth-tokens', this.getAuthTokens, 'auth-tokens', RequireAuthMiddleware);
this.post('/gen-auth-token', this.postGenAuthToken, 'generate-token', RequireAuthMiddleware); this.post('/gen-auth-token', this.postGenAuthToken, 'generate-token', RequireAuthMiddleware);
this.post('/revoke-auth-token/:id', this.postRevokeAuthToken, 'revoke-token', RequireAuthMiddleware); this.post('/revoke-auth-token/:id', this.postRevokeAuthToken, 'revoke-token', RequireAuthMiddleware);
} }
public async getAuthTokens(req: Request, res: Response): Promise<void> {
const allowedDomains = config.get<string[]>('allowed_url_domains');
const user = req.as(RequireAuthMiddleware).getUser();
res.render('auth-tokens', {
allowed_domains: allowedDomains,
default_domain: allowedDomains[config.get<number>('default_url_domain_for_files')],
auth_tokens: await AuthToken.select().where('user_id', user.id).get(),
});
}
protected async postGenAuthToken(req: Request, res: Response): Promise<void> { protected async postGenAuthToken(req: Request, res: Response): Promise<void> {
const user = req.as(RequireAuthMiddleware).getUser(); const user = req.as(RequireAuthMiddleware).getUser();
const authToken = AuthToken.create({ const authToken = AuthToken.create({

View File

@ -1,4 +1,53 @@
{% extends 'layouts/base.njk' %}
{% set title = app.name + ' - Auth tokens' %}
{% block body %}
<div class="container"> <div class="container">
<section class="panel">
<h2><i data-feather="key"></i> Auth tokens</h2>
<form action="{{ route('generate-token') }}" method="POST">
{{ macros.csrf(getCsrfToken) }}
<button type="submit"><i data-feather="plus"></i> Generate a new token</button>
</form>
<table class="data-table">
<thead>
<tr>
<th>#</th>
<th class="table-col-grow">Secret</th>
<th>Created at</th>
<th>Last used at</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for token in auth_tokens %}
<tr>
<td>{{ token.id }}</td>
<td>
<div class="copyable-text">
<div class="content">{{ token.secret }}</div>
<button class="copy-button"><i data-feather="copy"></i></button>
</div>
</td>
<td>{{ token.created_at.toISOString() }}</td>
<td>{{ token.used_at.toISOString() }}</td>
<td class="actions">
<form action="{{ route('revoke-token', token.id) }}" method="POST">
<button class="button danger"><i data-feather="trash"></i> <span class="tip">Revoke</span></button>
{{ macros.csrf(getCsrfToken) }}
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
<section class="panel"> <section class="panel">
<h2><i data-feather="tool"></i> Setup a desktop utility</h2> <h2><i data-feather="tool"></i> Setup a desktop utility</h2>
<p>There may be a desktop client at some point. For now, if you're an advanced user, you can setup <p>There may be a desktop client at some point. For now, if you're an advanced user, you can setup
@ -32,8 +81,8 @@
<p>Examples:</p> <p>Examples:</p>
<pre>upload_file.sh path/to/file</pre> <pre>upload_file.sh path/to/file</pre>
<pre>upload_file.sh path/to/file my_very_important_file.png</pre> <pre>upload_file.sh path/to/file my_very_important_file.png</pre>
<pre>shrink_url.sh https://gitlab.com/ArisuOngaku/ilyli</pre> <pre>shrink_url.sh https://eternae.ink/ashpie/ily.li</pre>
<pre>shrink_url.sh https://gitlab.com/ArisuOngaku/ilyli repo</pre> <pre>shrink_url.sh https://eternae.ink/ashpie/ily.li repo</pre>
</section> </section>
<hr> <hr>
@ -114,46 +163,5 @@
<p>For examples with curl, please download and review the scripts above.</p> <p>For examples with curl, please download and review the scripts above.</p>
</section> </section>
</section> </section>
<section class="panel">
<h2><i data-feather="key"></i> Auth tokens</h2>
<form action="{{ route('generate-token') }}" method="POST">
{{ macros.csrf(getCsrfToken) }}
<button type="submit"><i data-feather="plus"></i> Generate a new token</button>
</form>
<table class="data-table">
<thead>
<tr>
<th>#</th>
<th class="table-col-grow">Secret</th>
<th>Created at</th>
<th>Last used at</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for token in auth_tokens %}
<tr>
<td>{{ token.id }}</td>
<td>
<div class="copyable-text">
<div class="content">{{ token.secret }}</div>
<button class="copy-button"><i data-feather="copy"></i></button>
</div>
</td>
<td>{{ token.created_at.toISOString() }}</td>
<td>{{ token.used_at.toISOString() }}</td>
<td class="actions">
<form action="{{ route('revoke-token', token.id) }}" method="POST">
<button class="button danger"><i data-feather="trash"></i> <span class="tip">Revoke</span></button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</div> </div>
{% endblock %}

View File

@ -25,6 +25,7 @@
{% endif %} {% endif %}
<li><a href="{{ route('account') }}"><i data-feather="user"></i> <span class="tip">{{ user.name | default('Account') }}</span></a> <li><a href="{{ route('account') }}"><i data-feather="user"></i> <span class="tip">{{ user.name | default('Account') }}</span></a>
<ul class="dropdown"> <ul class="dropdown">
<li><a href="{{ route('auth-tokens') }}"><i data-feather="key"></i> <span class="tip">Manage auth tokens</span></a></li>
<li> <li>
<hr> <hr>
<form action="{{ route('logout') }}?{{ querystring.stringify({redirect_uri: '/'}) }}" method="POST"> <form action="{{ route('logout') }}?{{ querystring.stringify({redirect_uri: '/'}) }}" method="POST">