diff options
| author | Pitu <[email protected]> | 2019-02-21 23:49:29 +0900 |
|---|---|---|
| committer | Pitu <[email protected]> | 2019-02-21 23:49:29 +0900 |
| commit | 44e6fd31d2fa7761c90ff1d6932cf69d163b22e8 (patch) | |
| tree | caa404d59b5817e5a302df55d66a740765fc24d2 /src | |
| parent | derp (diff) | |
| download | host.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.js | 69 | ||||
| -rw-r--r-- | src/api/database/seeds/initial.js | 32 | ||||
| -rw-r--r-- | src/api/structures/Database.js | 112 | ||||
| -rw-r--r-- | src/api/structures/Server.js | 2 | ||||
| -rw-r--r-- | src/wizard.js | 44 |
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(); } |