Add redirection functionality and remove unused resources

This commit is contained in:
Alice Gaudon 2020-11-16 16:55:04 +01:00
parent ba5b90a4f9
commit 442166229e
11 changed files with 9601 additions and 159 deletions

View File

@ -1,43 +1,14 @@
{
app: {
name: 'Example App',
contact_email: 'contact@example.net'
name: 'Eternae Ink Update',
contact_email: 'contact@eternae.ink',
},
log_level: "DEV",
db_log_level: "ERROR",
public_url: "http://localhost:4899",
public_websocket_url: "ws://localhost:4899",
gitea_instance_url: 'https://eternae.ink',
port: 4899,
mysql: {
connectionLimit: 10,
host: "localhost",
user: "root",
password: "",
database: "example_app",
create_database_automatically: false
},
redis: {
host: "127.0.0.1",
port: 6379,
prefix: 'example_app'
},
session: {
cookie: {
secure: false
}
},
mail: {
host: "127.0.0.1",
port: "1025",
secure: false,
username: "",
password: "",
allow_invalid_tls: true,
from: 'contact@example.net',
from_name: 'Example App',
},
view: {
cache: false
cache: false,
},
approval_mode: false,
}

View File

@ -1,15 +1,5 @@
{
log_level: "DEBUG",
db_log_level: "ERROR",
public_url: "https://watch-my.stream",
public_websocket_url: "wss://watch-my.stream",
session: {
cookie: {
secure: true
}
},
mail: {
secure: true,
allow_invalid_tls: false
}
public_url: "https://update.eternae.ink",
}

View File

@ -1,9 +1 @@
{
mysql: {
host: "localhost",
user: "root",
password: "",
database: "swaf_test",
create_database_automatically: true
}
}
{}

View File

@ -1,24 +1,10 @@
import Application from "swaf/Application";
import Migration, {MigrationType} from "swaf/db/Migration";
import CreateMigrationsTable from "swaf/migrations/CreateMigrationsTable";
import ExpressAppComponent from "swaf/components/ExpressAppComponent";
import NunjucksComponent from "swaf/components/NunjucksComponent";
import MysqlComponent from "swaf/components/MysqlComponent";
import LogRequestsComponent from "swaf/components/LogRequestsComponent";
import RedisComponent from "swaf/components/RedisComponent";
import ServeStaticDirectoryComponent from "swaf/components/ServeStaticDirectoryComponent";
import MaintenanceComponent from "swaf/components/MaintenanceComponent";
import MailComponent from "swaf/components/MailComponent";
import SessionComponent from "swaf/components/SessionComponent";
import RedirectBackComponent from "swaf/components/RedirectBackComponent";
import FormHelperComponent from "swaf/components/FormHelperComponent";
import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent";
import WebSocketServerComponent from "swaf/components/WebSocketServerComponent";
import HomeController from "./controllers/HomeController";
import AutoUpdateComponent from "swaf/components/AutoUpdateComponent";
import GiteaRepoLatestReleaseController from "./controllers/GiteaRepoLatestReleaseController";
import NunjucksComponent from "swaf/components/NunjucksComponent";
import packageJson = require('../package.json');
import DummyMigration from "swaf/migrations/DummyMigration";
import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable";
export default class App extends Application {
public constructor(
@ -29,62 +15,21 @@ export default class App extends Application {
}
protected getMigrations(): MigrationType<Migration>[] {
return [
CreateMigrationsTable,
DummyMigration,
DropLegacyLogsTable,
];
return [];
}
protected async init(): Promise<void> {
this.registerComponents();
this.registerWebSocketListeners();
this.registerControllers();
}
private registerComponents() {
const redisComponent = new RedisComponent();
const mysqlComponent = new MysqlComponent();
const expressAppComponent = new ExpressAppComponent(this.addr, this.port);
this.use(expressAppComponent);
this.use(new ExpressAppComponent(this.addr, this.port));
this.use(new NunjucksComponent());
this.use(new LogRequestsComponent());
// Static files
this.use(new ServeStaticDirectoryComponent('public'));
this.use(new ServeStaticDirectoryComponent('node_modules/feather-icons/dist', '/icons'));
// Maintenance
this.use(new MaintenanceComponent(this, () => {
return redisComponent.canServe() && mysqlComponent.canServe();
}));
this.use(new AutoUpdateComponent());
// Services
this.use(mysqlComponent);
this.use(new MailComponent());
// Session
this.use(redisComponent);
this.use(new SessionComponent(redisComponent));
// Utils
this.use(new RedirectBackComponent());
this.use(new FormHelperComponent());
// Middlewares
this.use(new CsrfProtectionComponent());
// WebSocket server
this.use(new WebSocketServerComponent(this, expressAppComponent, redisComponent));
}
private registerWebSocketListeners() {
// WebSocket listeners
}
private registerControllers() {
this.use(new HomeController());
this.use(new GiteaRepoLatestReleaseController());
}
}

View File

@ -0,0 +1,45 @@
import Controller from "swaf/Controller";
import {NextFunction, Request, Response} from "express";
import * as https from "https";
import config from "config";
import {log} from "swaf/Logger";
export default class GiteaRepoLatestReleaseController extends Controller {
public routes(): void {
this.get('/:owner/:name/:file?', this.getFile, 'get-repo-release-file');
}
protected async getFile(req: Request, res: Response, next: NextFunction): Promise<void> {
log.info('Serving ' + req.path + ' ...');
const {owner, name, file} = req.params;
if (!owner || !name) return next();
https.get(`${config.get('gitea_instance_url')}/api/v1/repos/${owner}/${name}/releases?limit=1`, {
headers: {
'Accept': 'application/json',
},
}, r => {
let data = '';
r.on('data', c => {
data += c;
});
r.on('end', () => {
const assets = JSON.parse(data)[0].assets;
if (file) {
for (const asset of assets) {
if (asset.name === file) {
log.debug('Redirect to', asset.browser_download_url);
return res.redirect(302, asset.browser_download_url);
}
}
} else {
log.debug('List files');
return res.render('list-files', {assets: assets});
}
});
}).on('error', err => {
log.error(err);
});
}
}

View File

@ -1,25 +0,0 @@
import Controller from "swaf/Controller";
import {Request, Response} from "express";
export default class HomeController extends Controller {
public routes(): void {
this.get('/', this.getHome, 'home');
this.get('/about', this.getAbout, 'about');
this.get('/back', this.goBack, 'about');
}
protected async getHome(req: Request, res: Response): Promise<void> {
res.render('home');
}
protected async getAbout(req: Request, res: Response): Promise<void> {
res.render('about');
}
/**
* This is to test and assert that swaf extended types are available
*/
protected async goBack(req: Request, res: Response): Promise<void> {
res.redirectBack();
}
}

View File

@ -1,14 +0,0 @@
{% extends 'layouts/base.njk' %}
{% set title = app.name + ' - About us' %}
{% block body %}
<h1>Very interesting</h1>
<div class="container">
<section class="panel">
<h2>This is us</h2>
<p class="center">And we like swaf!</p>
</section>
</div>
{% endblock %}

28
views/errors/error.njk Normal file
View File

@ -0,0 +1,28 @@
{% extends 'layouts/barebone.njk' %}
{% set title = error_code + ' - ' + error_message %}
{% block _stylesheets %}
<link rel="stylesheet" href="/css/error.css">
{% endblock %}
{% block _body %}
<div class="logo"><a href="/">{{ app.name }}</a></div>
<main class="{% block class %}{% endblock %}">
{% if flash %}
{{ macros.messages(flash) }}
{% endif %}
<div class="error-code">{{ error_code }}</div>
<div class="error-message">{{ error_message }}</div>
<div class="error-instructions">{{ error_instructions|safe }}</div>
</main>
<div class="contact">
Error ID: {{ error_id }}
<br>
If you think this isn't right, please contact us with the above error ID at
<a href="mailto:{{ app.contact_email }}">{{ app.contact_email }}</a>.
</div>
{% endblock %}

View File

@ -1,7 +0,0 @@
{% extends 'layouts/base.njk' %}
{% set title = app.name + ' - Hello world!' %}
{% block body %}
<h1>Hello world!</h1>
{% endblock %}

5
views/list-files.njk Normal file
View File

@ -0,0 +1,5 @@
<ul>
{% for asset in assets %}
<li>#{{ asset.id }} - <a href="{{ asset.browser_download_url }}">{{ asset.name }}</a> ({{ asset.size }}, {{ asset.download_count }}, {{ asset.uuid }})</li>
{% endfor %}
</ul>

9512
yarn.lock Normal file

File diff suppressed because it is too large Load Diff