aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPitu <[email protected]>2019-02-21 23:49:29 +0900
committerPitu <[email protected]>2019-02-21 23:49:29 +0900
commit44e6fd31d2fa7761c90ff1d6932cf69d163b22e8 (patch)
treecaa404d59b5817e5a302df55d66a740765fc24d2 /src
parentderp (diff)
downloadhost.fuwn.me-44e6fd31d2fa7761c90ff1d6932cf69d163b22e8.tar.xz
host.fuwn.me-44e6fd31d2fa7761c90ff1d6932cf69d163b22e8.zip
Database migration and seeding
Diffstat (limited to 'src')
-rw-r--r--src/api/database/migrations/20190221225812_initialMigration.js69
-rw-r--r--src/api/database/seeds/initial.js32
-rw-r--r--src/api/structures/Database.js112
-rw-r--r--src/api/structures/Server.js2
-rw-r--r--src/wizard.js44
5 files changed, 138 insertions, 121 deletions
diff --git a/src/api/database/migrations/20190221225812_initialMigration.js b/src/api/database/migrations/20190221225812_initialMigration.js
new file mode 100644
index 0000000..455d5c5
--- /dev/null
+++ b/src/api/database/migrations/20190221225812_initialMigration.js
@@ -0,0 +1,69 @@
+exports.up = async knex => {
+ await knex.schema.createTable('users', table => {
+ table.increments();
+ table.string('username');
+ table.string('password');
+ table.boolean('enabled').defaultTo(true);
+ table.boolean('isAdmin').defaultTo(false);
+ table.string('apiKey');
+ table.timestamp('passwordEditedAt');
+ table.timestamp('apiKeyEditedAt');
+ table.timestamp('createdAt');
+ table.timestamp('editedAt');
+ });
+
+ await knex.schema.createTable('albums', table => {
+ table.increments();
+ table.integer('userId');
+ table.string('name');
+ table.timestamp('zippedAt');
+ table.timestamp('createdAt');
+ table.timestamp('editedAt');
+ });
+
+ await knex.schema.createTable('files', table => {
+ table.increments();
+ table.integer('userId');
+ table.string('name');
+ table.string('original');
+ table.string('type');
+ table.integer('size');
+ table.string('hash');
+ table.string('ip');
+ table.timestamp('createdAt');
+ table.timestamp('editedAt');
+ });
+
+ await knex.schema.createTable('links', table => {
+ table.increments();
+ table.integer('userId');
+ table.integer('albumId');
+ table.string('identifier');
+ table.integer('views').defaultTo(0);
+ table.boolean('enabled').defaultTo(true);
+ table.boolean('enableDownload').defaultTo(true);
+ table.timestamp('expiresAt');
+ table.timestamp('createdAt');
+ table.timestamp('editedAt');
+ });
+
+ await knex.schema.createTable('albumsFiles', table => {
+ table.increments();
+ table.integer('albumId');
+ table.integer('fileId');
+ });
+
+ await knex.schema.createTable('albumsLinks', table => {
+ table.increments();
+ table.integer('albumId');
+ table.integer('linkId');
+ });
+};
+exports.down = async knex => {
+ await knex.schema.dropTableIfExists('users');
+ await knex.schema.dropTableIfExists('albums');
+ await knex.schema.dropTableIfExists('files');
+ await knex.schema.dropTableIfExists('links');
+ await knex.schema.dropTableIfExists('albumsFiles');
+ await knex.schema.dropTableIfExists('albumsLinks');
+};
diff --git a/src/api/database/seeds/initial.js b/src/api/database/seeds/initial.js
new file mode 100644
index 0000000..d4a343c
--- /dev/null
+++ b/src/api/database/seeds/initial.js
@@ -0,0 +1,32 @@
+const bcrypt = require('bcrypt');
+const moment = require('moment');
+const randomstring = require('randomstring');
+
+exports.seed = async db => {
+ const now = moment.utc().toDate();
+ const user = await db.table('users').where({ username: 'root' }).first();
+ if (user) return;
+ try {
+ const hash = await bcrypt.hash(process.env.ADMIN_PASSWORD, 10);
+ await db.table('users').insert({
+ username: process.env.ADMIN_ACCOUNT,
+ password: hash,
+ apiKey: randomstring.generate(64),
+ passwordEditedAt: now,
+ apiKeyEditedAt: now,
+ createdAt: now,
+ editedAt: now,
+ isAdmin: true
+ });
+ console.log();
+ console.log('====================================================');
+ console.log('== Successfully created the admin account. ==');
+ console.log('====================================================');
+ console.log('== Run `yarn api` and `yarn site` next ==');
+ console.log('== preferably with pm2 or tmux to keep them alive ==');
+ console.log('====================================================');
+ console.log();
+ } catch (error) {
+ console.error(error);
+ }
+}
diff --git a/src/api/structures/Database.js b/src/api/structures/Database.js
deleted file mode 100644
index 76ea006..0000000
--- a/src/api/structures/Database.js
+++ /dev/null
@@ -1,112 +0,0 @@
-const log = require('../utils/Log');
-const { server } = require('../../../config');
-const db = require('knex')(server.database);
-const bcrypt = require('bcrypt');
-const moment = require('moment');
-const randomstring = require('randomstring');
-
-class Database {
- constructor() {
- this.createTables();
- }
-
- async createTables() {
- if (!await db.schema.hasTable('users')) {
- await db.schema.createTable('users', table => {
- table.increments();
- table.string('username');
- table.string('password');
- table.boolean('enabled').defaultTo(true);
- table.boolean('isAdmin').defaultTo(false);
- table.string('apiKey');
- table.timestamp('passwordEditedAt');
- table.timestamp('apiKeyEditedAt');
- table.timestamp('createdAt');
- table.timestamp('editedAt');
- });
- }
-
- if (!await db.schema.hasTable('albums')) {
- await db.schema.createTable('albums', table => {
- table.increments();
- table.integer('userId');
- table.string('name');
- // table.string('identifier');
- // table.boolean('enabled');
- // table.boolean('enableDownload').defaultTo(true);
- table.timestamp('zippedAt');
- table.timestamp('createdAt');
- table.timestamp('editedAt');
- });
- }
-
- if (!await db.schema.hasTable('files')) {
- await db.schema.createTable('files', table => {
- table.increments();
- table.integer('userId');
- table.string('name');
- table.string('original');
- table.string('type');
- table.integer('size');
- table.string('hash');
- table.string('ip');
- table.timestamp('createdAt');
- table.timestamp('editedAt');
- });
- }
-
- if (!await db.schema.hasTable('links')) {
- await db.schema.createTable('links', table => {
- table.increments();
- table.integer('userId');
- table.integer('albumId');
- table.string('identifier');
- table.integer('views').defaultTo(0);
- table.boolean('enabled').defaultTo(true);
- table.boolean('enableDownload').defaultTo(true);
- table.timestamp('expiresAt');
- table.timestamp('createdAt');
- table.timestamp('editedAt');
- });
- }
-
- if (!await db.schema.hasTable('albumsFiles')) {
- await db.schema.createTable('albumsFiles', table => {
- table.increments();
- table.integer('albumId');
- table.integer('fileId');
- });
- }
-
- if (!await db.schema.hasTable('albumsLinks')) {
- await db.schema.createTable('albumsLinks', table => {
- table.increments();
- table.integer('albumId');
- table.integer('linkId');
- });
- }
-
- const now = moment.utc().toDate();
- const user = await db.table('users').where({ username: 'root' }).first();
- if (user) return;
- try {
- const hash = await bcrypt.hash('root', 10);
- await db.table('users').insert({
- username: 'root',
- password: hash,
- apiKey: randomstring.generate(64),
- passwordEditedAt: now,
- apiKeyEditedAt: now,
- createdAt: now,
- editedAt: now,
- isAdmin: true
- });
- log.success('Successfully created the root user with password "root". Make sure to log in and change it!');
- } catch (error) {
- log.error(error);
- if (error) log.error('Error generating password hash for root');
- }
- }
-}
-
-module.exports = Database;
diff --git a/src/api/structures/Server.js b/src/api/structures/Server.js
index dc72558..d2cc2f1 100644
--- a/src/api/structures/Server.js
+++ b/src/api/structures/Server.js
@@ -8,7 +8,6 @@ const RateLimit = require('express-rate-limit');
const bodyParser = require('body-parser');
const jetpack = require('fs-jetpack');
const path = require('path');
-const Database = require('./Database');
const rateLimiter = new RateLimit({
windowMs: process.env.RATE_LIMIT_WINDOW,
@@ -35,7 +34,6 @@ class Server {
this.server.use(bodyParser.json());
// this.server.use(rateLimiter);
this.routesFolder = path.join(__dirname, '..', 'routes');
- this.database = new Database();
}
registerAllTheRoutes() {
diff --git a/src/wizard.js b/src/wizard.js
index affa759..3094488 100644
--- a/src/wizard.js
+++ b/src/wizard.js
@@ -1,3 +1,4 @@
+const randomstring = require('randomstring');
const jetpack = require('fs-jetpack');
const qoa = require('qoa');
qoa.config({
@@ -15,6 +16,10 @@ async function start() {
});
if (!confirm.run) process.exit(0);
+ console.log();
+ console.log('You can manually edit .env file after the wizard to edit values');
+ console.log();
+
const wizard = [
{
type: 'input',
@@ -94,9 +99,34 @@ async function start() {
deny: 'n'
},
{
+ type: 'input',
+ query: 'Name of the admin account?',
+ handle: 'ADMIN_ACCOUNT'
+ },
+ {
type: 'secure',
query: 'Type a secure password for the root user:',
- handle: 'ROOT_PASSWORD'
+ handle: 'ADMIN_PASSWORD'
+ },
+ {
+ type: 'input',
+ query: 'Database host',
+ handle: 'DB_HOST'
+ },
+ {
+ type: 'input',
+ query: 'Database user',
+ handle: 'DB_USER'
+ },
+ {
+ type: 'input',
+ query: 'Database password',
+ handle: 'DB_PASSWORD'
+ },
+ {
+ type: 'input',
+ query: 'Database name',
+ handle: 'DB_DATABASE'
}
];
@@ -109,13 +139,9 @@ async function start() {
RATE_LIMIT_WINDOW: 2,
RATE_LIMIT_MAX: 5,
DB_CLIENT: 'pg',
- DB_HOST: 'localhost',
- DB_USER: '',
- DB_PASSWORD: '',
- DB_DATABASE: '',
BLOCKED_EXTENSIONS: ['.jar', '.exe', '.msi', '.com', '.bat', '.cmd', '.scr', '.ps1', '.sh'],
UPLOAD_FOLDER: 'uploads',
- SECRET: 'SuperSecretPassphraseHere',
+ SECRET: randomstring.generate(64),
MAX_LINKS_PER_ALBUM: 5
};
@@ -128,7 +154,11 @@ async function start() {
jetpack.write('.env', envfile);
console.log();
- console.log('== .env file generated successfully. You can now run lolisafe ==');
+ console.log('=============================================');
+ console.log('== .env file generated successfully. ==');
+ console.log('=============================================');
+ console.log('== Run `yarn migrate` and `yarn seed` next ==');
+ console.log('=============================================');
console.log();
}