Update to swaf 0.23.4
This commit is contained in:
parent
c6b4c2dfe3
commit
d6f4d612fe
69
src/App.ts
69
src/App.ts
@ -15,31 +15,34 @@ import CsrfProtectionComponent from "swaf/components/CsrfProtectionComponent";
|
|||||||
import WebSocketServerComponent from "swaf/components/WebSocketServerComponent";
|
import WebSocketServerComponent from "swaf/components/WebSocketServerComponent";
|
||||||
import AboutController from "./controllers/AboutController";
|
import AboutController from "./controllers/AboutController";
|
||||||
import AutoUpdateComponent from "swaf/components/AutoUpdateComponent";
|
import AutoUpdateComponent from "swaf/components/AutoUpdateComponent";
|
||||||
import AuthController from "./controllers/AuthController";
|
|
||||||
import MagicLinkWebSocketListener from "swaf/auth/magic_link/MagicLinkWebSocketListener";
|
import MagicLinkWebSocketListener from "swaf/auth/magic_link/MagicLinkWebSocketListener";
|
||||||
import MagicLinkController from "./controllers/MagicLinkController";
|
|
||||||
import MailController from "swaf/auth/MailController";
|
|
||||||
import FileController from "./controllers/FileController";
|
import FileController from "./controllers/FileController";
|
||||||
import CreateUsersAndUserEmailsTable from "swaf/auth/migrations/CreateUsersAndUserEmailsTable";
|
|
||||||
import CreateMagicLinksTable from "swaf/auth/migrations/CreateMagicLinksTable";
|
|
||||||
import CreateAuthTokensTable from "./migrations/CreateAuthTokensTable";
|
import CreateAuthTokensTable from "./migrations/CreateAuthTokensTable";
|
||||||
import AuthComponent from "swaf/auth/AuthComponent";
|
import AuthComponent from "swaf/auth/AuthComponent";
|
||||||
import AuthGuard from "swaf/auth/AuthGuard";
|
|
||||||
import MagicLink from "swaf/auth/models/MagicLink";
|
|
||||||
import AuthToken from "./models/AuthToken";
|
|
||||||
import {MagicLinkActionType} from "./controllers/MagicLinkActionType";
|
|
||||||
import {Request} from "express";
|
|
||||||
import CreateFilesTable from "./migrations/CreateFilesTable";
|
import CreateFilesTable from "./migrations/CreateFilesTable";
|
||||||
import IncreaseFilesSizeField from "./migrations/IncreaseFilesSizeField";
|
import IncreaseFilesSizeField from "./migrations/IncreaseFilesSizeField";
|
||||||
import AddApprovedFieldToUsersTable from "swaf/auth/migrations/AddApprovedFieldToUsersTable";
|
|
||||||
import CreateUrlRedirectsTable from "./migrations/CreateUrlRedirectsTable";
|
import CreateUrlRedirectsTable from "./migrations/CreateUrlRedirectsTable";
|
||||||
import AuthTokenController from "./controllers/AuthTokenController";
|
import AuthTokenController from "./controllers/AuthTokenController";
|
||||||
import URLRedirectController from "./controllers/URLRedirectController";
|
import URLRedirectController from "./controllers/URLRedirectController";
|
||||||
import LinkController from "./controllers/LinkController";
|
import LinkController from "./controllers/LinkController";
|
||||||
import BackendController from "swaf/helpers/BackendController";
|
import BackendController from "swaf/helpers/BackendController";
|
||||||
import RedirectBackComponent from "swaf/components/RedirectBackComponent";
|
|
||||||
import DummyMigration from "swaf/migrations/DummyMigration";
|
import DummyMigration from "swaf/migrations/DummyMigration";
|
||||||
import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable";
|
import DropLegacyLogsTable from "swaf/migrations/DropLegacyLogsTable";
|
||||||
|
import CreateUsersAndUserEmailsTableMigration from "swaf/auth/migrations/CreateUsersAndUserEmailsTableMigration";
|
||||||
|
import CreateMagicLinksTableMigration from "swaf/auth/magic_link/CreateMagicLinksTableMigration";
|
||||||
|
import AddApprovedFieldToUsersTableMigration from "swaf/auth/migrations/AddApprovedFieldToUsersTableMigration";
|
||||||
|
import PreviousUrlComponent from "swaf/components/PreviousUrlComponent";
|
||||||
|
import MagicLinkAuthMethod from "swaf/auth/magic_link/MagicLinkAuthMethod";
|
||||||
|
import {MAGIC_LINK_MAIL} from "swaf/Mails";
|
||||||
|
import PasswordAuthMethod from "swaf/auth/password/PasswordAuthMethod";
|
||||||
|
import MailController from "swaf/mail/MailController";
|
||||||
|
import AccountController from "swaf/auth/AccountController";
|
||||||
|
import AuthController from "swaf/auth/AuthController";
|
||||||
|
import MagicLinkController from "swaf/auth/magic_link/MagicLinkController";
|
||||||
|
import AddUsedToMagicLinksMigration from "swaf/auth/magic_link/AddUsedToMagicLinksMigration";
|
||||||
|
import MakeMagicLinksSessionNotUniqueMigration from "swaf/auth/magic_link/MakeMagicLinksSessionNotUniqueMigration";
|
||||||
|
import AddPasswordToUsersMigration from "swaf/auth/password/AddPasswordToUsersMigration";
|
||||||
|
import DropNameFromUsers from "swaf/auth/migrations/DropNameFromUsers";
|
||||||
import packageJson = require('./package.json');
|
import packageJson = require('./package.json');
|
||||||
|
|
||||||
export default class App extends Application {
|
export default class App extends Application {
|
||||||
@ -54,15 +57,19 @@ export default class App extends Application {
|
|||||||
return [
|
return [
|
||||||
CreateMigrationsTable,
|
CreateMigrationsTable,
|
||||||
DummyMigration,
|
DummyMigration,
|
||||||
CreateUsersAndUserEmailsTable,
|
CreateUsersAndUserEmailsTableMigration,
|
||||||
CreateMagicLinksTable,
|
CreateMagicLinksTableMigration,
|
||||||
CreateAuthTokensTable,
|
CreateAuthTokensTable,
|
||||||
CreateFilesTable,
|
CreateFilesTable,
|
||||||
IncreaseFilesSizeField,
|
IncreaseFilesSizeField,
|
||||||
AddApprovedFieldToUsersTable,
|
AddApprovedFieldToUsersTableMigration,
|
||||||
CreateUrlRedirectsTable,
|
CreateUrlRedirectsTable,
|
||||||
DropLegacyLogsTable,
|
DropLegacyLogsTable,
|
||||||
FixUserMainEmailRelation,
|
DummyMigration,
|
||||||
|
AddUsedToMagicLinksMigration,
|
||||||
|
MakeMagicLinksSessionNotUniqueMigration,
|
||||||
|
AddPasswordToUsersMigration,
|
||||||
|
DropNameFromUsers,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,28 +105,7 @@ export default class App extends Application {
|
|||||||
// Session
|
// Session
|
||||||
this.use(new RedisComponent());
|
this.use(new RedisComponent());
|
||||||
this.use(new SessionComponent(this.as(RedisComponent)));
|
this.use(new SessionComponent(this.as(RedisComponent)));
|
||||||
this.use(new AuthComponent(new class extends AuthGuard<MagicLink | AuthToken> {
|
this.use(new AuthComponent(this, new MagicLinkAuthMethod(this, MAGIC_LINK_MAIL), new PasswordAuthMethod(this)));
|
||||||
public async getProofForSession(session: Session): Promise<MagicLink | AuthToken | null> {
|
|
||||||
return await MagicLink.bySessionId(
|
|
||||||
session.id,
|
|
||||||
[MagicLinkActionType.LOGIN, MagicLinkActionType.REGISTER],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getProofForRequest(req: Request): Promise<MagicLink | AuthToken | null> {
|
|
||||||
const authorization = req.header('Authorization');
|
|
||||||
if (authorization) {
|
|
||||||
const token = await AuthToken.select().where('secret', authorization).first();
|
|
||||||
if (token) {
|
|
||||||
token.use();
|
|
||||||
await token.save();
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await super.getProofForRequest(req);
|
|
||||||
}
|
|
||||||
}(this)));
|
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
this.use(new FormHelperComponent());
|
this.use(new FormHelperComponent());
|
||||||
@ -140,12 +126,13 @@ export default class App extends Application {
|
|||||||
this.use(new LinkController());
|
this.use(new LinkController());
|
||||||
|
|
||||||
// Priority
|
// Priority
|
||||||
|
this.use(new MailController());
|
||||||
this.use(new AuthController());
|
this.use(new AuthController());
|
||||||
this.use(new MagicLinkController(this.as<MagicLinkWebSocketListener<this>>(MagicLinkWebSocketListener)));
|
this.use(new MagicLinkController(this.as<MagicLinkWebSocketListener<this>>(MagicLinkWebSocketListener)));
|
||||||
this.use(new BackendController());
|
|
||||||
|
|
||||||
// Core functionality
|
// Core
|
||||||
this.use(new MailController());
|
this.use(new AccountController());
|
||||||
|
this.use(new BackendController());
|
||||||
|
|
||||||
// Other functionality
|
// Other functionality
|
||||||
this.use(new AuthTokenController());
|
this.use(new AuthTokenController());
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import {cryptoRandomDictionary} from "swaf/Utils";
|
|
||||||
import config from "config";
|
import config from "config";
|
||||||
import FileModel from "./models/FileModel";
|
import FileModel from "./models/FileModel";
|
||||||
import {ServerError} from "swaf/HttpError";
|
import {ServerError} from "swaf/HttpError";
|
||||||
|
import {nanoid} from "nanoid";
|
||||||
|
|
||||||
const SLUG_DICTIONARY = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
||||||
export default async function generateSlug(tries: number): Promise<string> {
|
export default async function generateSlug(tries: number): Promise<string> {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
do {
|
do {
|
||||||
const slug = cryptoRandomDictionary(config.get<number>('newlyGeneratedSlugSize'), SLUG_DICTIONARY);
|
const slug = nanoid(config.get<number>('newlyGeneratedSlugSize'));
|
||||||
if (!await FileModel.getBySlug(slug)) {
|
if (!await FileModel.getBySlug(slug)) {
|
||||||
return slug;
|
return slug;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import MagicLinkAuthController from "swaf/auth/magic_link/MagicLinkAuthController";
|
|
||||||
import {MAGIC_LINK_MAIL} from "swaf/Mails";
|
|
||||||
|
|
||||||
export default class AuthController extends MagicLinkAuthController {
|
|
||||||
public constructor() {
|
|
||||||
super(MAGIC_LINK_MAIL);
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,7 +18,7 @@ export default class AuthTokenController extends Controller {
|
|||||||
});
|
});
|
||||||
await authToken.save();
|
await authToken.save();
|
||||||
req.flash('success', 'Successfully created auth token.');
|
req.flash('success', 'Successfully created auth token.');
|
||||||
res.redirectBack(Controller.route('file-upload'));
|
res.redirect(req.getPreviousUrl() || Controller.route('file-upload'));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async postRevokeAuthToken(req: Request, res: Response): Promise<void> {
|
protected async postRevokeAuthToken(req: Request, res: Response): Promise<void> {
|
||||||
@ -34,6 +34,6 @@ export default class AuthTokenController extends Controller {
|
|||||||
await authToken.delete();
|
await authToken.delete();
|
||||||
|
|
||||||
req.flash('success', 'Successfully deleted auth token.');
|
req.flash('success', 'Successfully deleted auth token.');
|
||||||
res.redirectBack(Controller.route('file-upload'));
|
res.redirect(req.getPreviousUrl() || Controller.route('file-upload'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import * as fs from "fs";
|
|||||||
import AuthToken from "../models/AuthToken";
|
import AuthToken from "../models/AuthToken";
|
||||||
import {IncomingForm} from "formidable";
|
import {IncomingForm} from "formidable";
|
||||||
import generateSlug from "../SlugGenerator";
|
import generateSlug from "../SlugGenerator";
|
||||||
import {log} from "swaf/Logger";
|
import {logger} from "swaf/Logger";
|
||||||
import FileUploadMiddleware from "swaf/FileUploadMiddleware";
|
import FileUploadMiddleware from "swaf/FileUploadMiddleware";
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +66,9 @@ export default class FileController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const upload = req.files['upload'];
|
const upload = req.files['upload'];
|
||||||
|
if (Array.isArray(upload)) {
|
||||||
|
throw new BadRequestError('Uploading multiple files at once is unsupported.', 'Please only upload one file at a time.', req.url);
|
||||||
|
}
|
||||||
|
|
||||||
// TTL
|
// TTL
|
||||||
let ttl = config.get<number>('default_file_ttl');
|
let ttl = config.get<number>('default_file_ttl');
|
||||||
@ -97,7 +100,7 @@ export default class FileController extends Controller {
|
|||||||
html: () => {
|
html: () => {
|
||||||
req.flash('success', 'Upload success!');
|
req.flash('success', 'Upload success!');
|
||||||
req.flash('url', file.getURL(domain));
|
req.flash('url', file.getURL(domain));
|
||||||
res.redirectBack('/');
|
res.redirect(Controller.route('file-manager'));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -132,7 +135,7 @@ export default class FileController extends Controller {
|
|||||||
text: () => res.send('success'),
|
text: () => res.send('success'),
|
||||||
html: () => {
|
html: () => {
|
||||||
req.flash('success', 'Successfully deleted file.');
|
req.flash('success', 'Successfully deleted file.');
|
||||||
res.redirectBack('/');
|
res.redirect(Controller.route('file-manager'));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -140,7 +143,7 @@ export default class FileController extends Controller {
|
|||||||
public static async deleteFile(file: FileModel): Promise<void> {
|
public static async deleteFile(file: FileModel): Promise<void> {
|
||||||
fs.unlinkSync(file.getOrFail('storage_path'));
|
fs.unlinkSync(file.getOrFail('storage_path'));
|
||||||
await file.delete();
|
await file.delete();
|
||||||
log.info('Deleted', file.storage_path, `(${file.real_name})`);
|
logger.info('Deleted', file.storage_path, `(${file.real_name})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import FileController, {FileUploadFormMiddleware} from "./FileController";
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {encodeRFC5987ValueChars} from "../Utils";
|
import {encodeRFC5987ValueChars} from "../Utils";
|
||||||
import {promisify} from "util";
|
import {promisify} from "util";
|
||||||
import {log} from "swaf/Logger";
|
import {logger} from "swaf/Logger";
|
||||||
|
|
||||||
export default class LinkController extends Controller {
|
export default class LinkController extends Controller {
|
||||||
public routes(): void {
|
public routes(): void {
|
||||||
@ -44,7 +44,7 @@ export default class LinkController extends Controller {
|
|||||||
|
|
||||||
// If file is bigger than max hotlink size, fallback to express download
|
// If file is bigger than max hotlink size, fallback to express download
|
||||||
if (stats.size > config.get<number>('max_hotlink_size') * 1024 * 1024) {
|
if (stats.size > config.get<number>('max_hotlink_size') * 1024 * 1024) {
|
||||||
log.info(`Fallback to express download for file of size ${stats.size}`);
|
logger.info(`Fallback to express download for file of size ${stats.size}`);
|
||||||
return res.download(file.getOrFail('storage_path'), fileName);
|
return res.download(file.getOrFail('storage_path'), fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import _MagicLinkController from "swaf/auth/magic_link/MagicLinkController";
|
|
||||||
import {Request, Response} from "express";
|
|
||||||
import Controller from "swaf/Controller";
|
|
||||||
import MagicLinkWebSocketListener from "swaf/auth/magic_link/MagicLinkWebSocketListener";
|
|
||||||
import MagicLink from "swaf/auth/models/MagicLink";
|
|
||||||
import AuthController from "./AuthController";
|
|
||||||
import {MagicLinkActionType} from "./MagicLinkActionType";
|
|
||||||
import App from "../App";
|
|
||||||
import AuthComponent from "swaf/auth/AuthComponent";
|
|
||||||
|
|
||||||
export default class MagicLinkController extends _MagicLinkController<App> {
|
|
||||||
public constructor(magicLinkWebSocketListener: MagicLinkWebSocketListener<App>) {
|
|
||||||
super(magicLinkWebSocketListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async performAction(magicLink: MagicLink, req: Request, res: Response): Promise<void> {
|
|
||||||
switch (magicLink.action_type) {
|
|
||||||
case MagicLinkActionType.LOGIN:
|
|
||||||
case MagicLinkActionType.REGISTER: {
|
|
||||||
await AuthController.checkAndAuth(req, res, magicLink);
|
|
||||||
const proof = await this.getApp().as(AuthComponent).getAuthGuard().isAuthenticated(req.getSession());
|
|
||||||
const user = await proof?.getResource();
|
|
||||||
|
|
||||||
if (!res.headersSent && user) {
|
|
||||||
// Auth success
|
|
||||||
req.flash('success', `Authentication success. Welcome, ${user.name}!`);
|
|
||||||
res.redirect(req.query.redirect_uri?.toString() || Controller.route('home'));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,13 +8,13 @@ import AuthToken from "../models/AuthToken";
|
|||||||
|
|
||||||
export default class URLRedirectController extends Controller {
|
export default class URLRedirectController extends Controller {
|
||||||
public routes(): void {
|
public routes(): void {
|
||||||
this.get('/url/shrink', this.getURLShrinker, 'url-shrinker', RequireAuthMiddleware);
|
this.get('/url/shrink', this.getUrlShrinker, 'url-shrinker', RequireAuthMiddleware);
|
||||||
this.get('/url/shrink/script', this.downloadLinuxScript, 'url-linux-script');
|
this.get('/url/shrink/script', this.downloadLinuxScript, 'url-linux-script');
|
||||||
this.post('/url/shrink', this.addURLFrontend, 'shrink-url', RequireAuthMiddleware);
|
this.post('/url/shrink', this.addUrlFrontend, 'shrink-url', RequireAuthMiddleware);
|
||||||
this.get('/urls/:page([0-9]+)?', this.getURLRedirectManager, 'url-manager', RequireAuthMiddleware);
|
this.get('/urls/:page([0-9]+)?', this.getUrlRedirectManager, 'url-manager', RequireAuthMiddleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getURLShrinker(req: Request, res: Response): Promise<void> {
|
protected async getUrlShrinker(req: Request, res: Response): Promise<void> {
|
||||||
const user = req.as(RequireAuthMiddleware).getUser();
|
const user = req.as(RequireAuthMiddleware).getUser();
|
||||||
const allowedDomains = config.get<string[]>('allowed_url_domains');
|
const allowedDomains = config.get<string[]>('allowed_url_domains');
|
||||||
res.render('url-shrinker', {
|
res.render('url-shrinker', {
|
||||||
@ -28,14 +28,14 @@ export default class URLRedirectController extends Controller {
|
|||||||
res.download('assets/files/shrink_url.sh', 'shrink_url.sh');
|
res.download('assets/files/shrink_url.sh', 'shrink_url.sh');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getURLRedirectManager(req: Request, res: Response): Promise<void> {
|
protected async getUrlRedirectManager(req: Request, res: Response): Promise<void> {
|
||||||
const user = req.as(RequireAuthMiddleware).getUser();
|
const user = req.as(RequireAuthMiddleware).getUser();
|
||||||
res.render('url-manager', {
|
res.render('url-manager', {
|
||||||
urls: await URLRedirect.paginateForUser(req, 100, user.getOrFail('id')),
|
urls: await URLRedirect.paginateForUser(req, 100, user.getOrFail('id')),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async addURLFrontend(req: Request, res: Response, next: NextFunction): Promise<void> {
|
protected async addUrlFrontend(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||||
req.body.type = 'url';
|
req.body.type = 'url';
|
||||||
await URLRedirectController.addURL(
|
await URLRedirectController.addURL(
|
||||||
req,
|
req,
|
||||||
@ -75,7 +75,7 @@ export default class URLRedirectController extends Controller {
|
|||||||
html: () => {
|
html: () => {
|
||||||
req.flash('success', 'URL shrunk successfully!');
|
req.flash('success', 'URL shrunk successfully!');
|
||||||
req.flash('url', urlRedirect.getURL(domain));
|
req.flash('url', urlRedirect.getURL(domain));
|
||||||
res.redirectBack('/');
|
res.redirect(Controller.route('url-manager'));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import {Connection} from "mysql";
|
|
||||||
import Migration from "swaf/db/Migration";
|
import Migration from "swaf/db/Migration";
|
||||||
import ModelFactory from "swaf/db/ModelFactory";
|
import ModelFactory from "swaf/db/ModelFactory";
|
||||||
import AuthToken from "../models/AuthToken";
|
import AuthToken from "../models/AuthToken";
|
||||||
|
|
||||||
export default class CreateAuthTokensTable extends Migration {
|
export default class CreateAuthTokensTable extends Migration {
|
||||||
public async install(connection: Connection): Promise<void> {
|
public async install(): Promise<void> {
|
||||||
await this.query(`CREATE TABLE auth_tokens
|
await this.query(`CREATE TABLE auth_tokens
|
||||||
(
|
(
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
@ -14,11 +13,11 @@ export default class CreateAuthTokensTable extends Migration {
|
|||||||
used_at DATETIME NOT NULL DEFAULT NOW(),
|
used_at DATETIME NOT NULL DEFAULT NOW(),
|
||||||
ttl INT UNSIGNED NOT NULL,
|
ttl INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
)`, connection);
|
)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async rollback(connection: Connection): Promise<void> {
|
public async rollback(): Promise<void> {
|
||||||
await this.query(`DROP TABLE IF EXISTS auth_tokens`, connection);
|
await this.query(`DROP TABLE IF EXISTS auth_tokens`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerModels(): void {
|
public registerModels(): void {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import {Connection} from "mysql";
|
|
||||||
import Migration from "swaf/db/Migration";
|
import Migration from "swaf/db/Migration";
|
||||||
import ModelFactory from "swaf/db/ModelFactory";
|
import ModelFactory from "swaf/db/ModelFactory";
|
||||||
import FileModel from "../models/FileModel";
|
import FileModel from "../models/FileModel";
|
||||||
|
|
||||||
export default class CreateFilesTable extends Migration {
|
export default class CreateFilesTable extends Migration {
|
||||||
public async install(connection: Connection): Promise<void> {
|
public async install(): Promise<void> {
|
||||||
await this.query(`CREATE TABLE files
|
await this.query(`CREATE TABLE files
|
||||||
(
|
(
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
@ -17,11 +16,11 @@ export default class CreateFilesTable extends Migration {
|
|||||||
created_at DATETIME NOT NULL DEFAULT NOW(),
|
created_at DATETIME NOT NULL DEFAULT NOW(),
|
||||||
ttl INT UNSIGNED NOT NULL,
|
ttl INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
)`, connection);
|
)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async rollback(connection: Connection): Promise<void> {
|
public async rollback(): Promise<void> {
|
||||||
await this.query(`DROP TABLE IF EXISTS files`, connection);
|
await this.query(`DROP TABLE IF EXISTS files`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerModels(): void {
|
public registerModels(): void {
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import Migration from "swaf/db/Migration";
|
import Migration from "swaf/db/Migration";
|
||||||
import {Connection} from "mysql";
|
|
||||||
import ModelFactory from "swaf/db/ModelFactory";
|
import ModelFactory from "swaf/db/ModelFactory";
|
||||||
import URLRedirect from "../models/URLRedirect";
|
import URLRedirect from "../models/URLRedirect";
|
||||||
|
|
||||||
export default class CreateUrlRedirectsTable extends Migration {
|
export default class CreateUrlRedirectsTable extends Migration {
|
||||||
public async install(connection: Connection): Promise<void> {
|
public async install(): Promise<void> {
|
||||||
await this.query(`CREATE TABLE url_redirects
|
await this.query(`CREATE TABLE url_redirects
|
||||||
(
|
(
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
@ -13,11 +12,11 @@ export default class CreateUrlRedirectsTable extends Migration {
|
|||||||
target_url VARCHAR(1745) NOT NULL,
|
target_url VARCHAR(1745) NOT NULL,
|
||||||
created_at DATETIME NOT NULL DEFAULT NOW(),
|
created_at DATETIME NOT NULL DEFAULT NOW(),
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
)`, connection);
|
)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async rollback(connection: Connection): Promise<void> {
|
public async rollback(): Promise<void> {
|
||||||
await this.query(`DROP TABLE IF EXISTS url_redirects`, connection);
|
await this.query(`DROP TABLE IF EXISTS url_redirects`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerModels(): void {
|
public registerModels(): void {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import Migration from "swaf/db/Migration";
|
import Migration from "swaf/db/Migration";
|
||||||
import {Connection} from "mysql";
|
|
||||||
|
|
||||||
export default class IncreaseFilesSizeField extends Migration {
|
export default class IncreaseFilesSizeField extends Migration {
|
||||||
public async install(connection: Connection): Promise<void> {
|
public async install(): Promise<void> {
|
||||||
await this.query(`ALTER TABLE files MODIFY size BIGINT UNSIGNED`, connection);
|
await this.query(`ALTER TABLE files MODIFY size BIGINT UNSIGNED`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async rollback(connection: Connection): Promise<void> {
|
public async rollback(): Promise<void> {
|
||||||
await this.query(`ALTER TABLE files MODIFY size INT UNSIGNED`, connection);
|
await this.query(`ALTER TABLE files MODIFY size INT UNSIGNED`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Model from "swaf/db/Model";
|
import Model from "swaf/db/Model";
|
||||||
import AuthProof from "swaf/auth/AuthProof";
|
import AuthProof from "swaf/auth/AuthProof";
|
||||||
import User from "swaf/auth/models/User";
|
import User from "swaf/auth/models/User";
|
||||||
import {cryptoRandomDictionary} from "swaf/Utils";
|
import {nanoid} from "nanoid";
|
||||||
|
|
||||||
export default class AuthToken extends Model implements AuthProof<User> {
|
export default class AuthToken extends Model implements AuthProof<User> {
|
||||||
public id?: number = undefined;
|
public id?: number = undefined;
|
||||||
@ -19,7 +19,7 @@ export default class AuthToken extends Model implements AuthProof<User> {
|
|||||||
|
|
||||||
protected async autoFill(): Promise<void> {
|
protected async autoFill(): Promise<void> {
|
||||||
if (!this.secret) {
|
if (!this.secret) {
|
||||||
this.secret = cryptoRandomDictionary(64, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_');
|
this.secret = nanoid(64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
{% if user.is_admin %}
|
{% if user.is_admin %}
|
||||||
<li><a href="{{ route('backend') }}"><i data-feather="settings"></i> <span class="tip">Backend</span></a></li>
|
<li><a href="{{ route('backend') }}"><i data-feather="settings"></i> <span class="tip">Backend</span></a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li><a href="{{ route('account') }}"><i data-feather="user"></i> <span class="tip">Account</span></a></li>
|
||||||
<li>
|
<li>
|
||||||
<form action="{{ route('logout') }}?{{ querystring.stringify({redirect_uri: '/'}) }}" method="POST">
|
<form action="{{ route('logout') }}?{{ querystring.stringify({redirect_uri: '/'}) }}" method="POST">
|
||||||
<button><i data-feather="log-out"></i> <span class="tip">Logout</span></button>
|
<button><i data-feather="log-out"></i> <span class="tip">Logout</span></button>
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -8934,9 +8934,9 @@ svgo@^1.3.2:
|
|||||||
util.promisify "~1.0.0"
|
util.promisify "~1.0.0"
|
||||||
|
|
||||||
swaf@^0.23.0:
|
swaf@^0.23.0:
|
||||||
version "0.23.2"
|
version "0.23.4"
|
||||||
resolved "https://registry.yarnpkg.com/swaf/-/swaf-0.23.2.tgz#11bc85a2909feb25a38ef6dbd15eb59ee4844cd6"
|
resolved "https://registry.yarnpkg.com/swaf/-/swaf-0.23.4.tgz#acaf9844bbbd16b4b3f793a6e9d48a4e194b916e"
|
||||||
integrity sha512-b89Z99PhBjms0YqFtn/uy01aG78ae3Zh0Q87lYdctUD4WAAa099dA0YviMC73TRp2meGkNfO4yuto7eXabgFwQ==
|
integrity sha512-8vUmJDUX7Ac31MngPW8GoDbBWXTWDClXTSGiSkuubCWpBLpEpdV8ChsTcNHGEc7zVl1YzuoiIZTXIkbXlrd+2A==
|
||||||
dependencies:
|
dependencies:
|
||||||
argon2 "^0.27.0"
|
argon2 "^0.27.0"
|
||||||
compression "^1.7.4"
|
compression "^1.7.4"
|
||||||
@ -9269,9 +9269,9 @@ tslog@^3.0.1:
|
|||||||
source-map-support "^0.5.19"
|
source-map-support "^0.5.19"
|
||||||
|
|
||||||
tsutils@^3.17.1:
|
tsutils@^3.17.1:
|
||||||
version "3.19.1"
|
version "3.20.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9"
|
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.20.0.tgz#ea03ea45462e146b53d70ce0893de453ff24f698"
|
||||||
integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==
|
integrity sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.8.1"
|
tslib "^1.8.1"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user