aboutsummaryrefslogtreecommitdiffstats
path: root/src/internal-server/start
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal-server/start')
-rw-r--r--src/internal-server/start/app.js61
-rw-r--r--src/internal-server/start/kernel.js55
-rw-r--r--src/internal-server/start/migrate.js46
-rw-r--r--src/internal-server/start/routes.js86
4 files changed, 248 insertions, 0 deletions
diff --git a/src/internal-server/start/app.js b/src/internal-server/start/app.js
new file mode 100644
index 000000000..8b1a49f57
--- /dev/null
+++ b/src/internal-server/start/app.js
@@ -0,0 +1,61 @@
1/*
2|--------------------------------------------------------------------------
3| Providers
4|--------------------------------------------------------------------------
5|
6| Providers are building blocks for your Adonis app. Anytime you install
7| a new Adonis specific package, chances are you will register the
8| provider here.
9|
10*/
11const providers = [
12 '@adonisjs/framework/providers/AppProvider',
13 '@adonisjs/bodyparser/providers/BodyParserProvider',
14 '@adonisjs/cors/providers/CorsProvider',
15 '@adonisjs/lucid/providers/LucidProvider',
16 '@adonisjs/drive/providers/DriveProvider',
17 '@adonisjs/validator/providers/ValidatorProvider',
18 '@adonisjs/framework/providers/ViewProvider',
19 '@adonisjs/shield/providers/ShieldProvider',
20];
21
22/*
23|--------------------------------------------------------------------------
24| Ace Providers
25|--------------------------------------------------------------------------
26|
27| Ace providers are required only when running ace commands. For example
28| Providers for migrations, tests etc.
29|
30*/
31const aceProviders = [
32 '@adonisjs/lucid/providers/MigrationsProvider',
33];
34
35/*
36|--------------------------------------------------------------------------
37| Aliases
38|--------------------------------------------------------------------------
39|
40| Aliases are short unique names for IoC container bindings. You are free
41| to create your own aliases.
42|
43| For example:
44| { Route: 'Adonis/Src/Route' }
45|
46*/
47const aliases = {};
48
49/*
50|--------------------------------------------------------------------------
51| Commands
52|--------------------------------------------------------------------------
53|
54| Here you store ace commands for your package
55|
56*/
57const commands = [];
58
59module.exports = {
60 providers, aceProviders, aliases, commands,
61};
diff --git a/src/internal-server/start/kernel.js b/src/internal-server/start/kernel.js
new file mode 100644
index 000000000..7b540f829
--- /dev/null
+++ b/src/internal-server/start/kernel.js
@@ -0,0 +1,55 @@
1/** @type {import('@adonisjs/framework/src/Server')} */
2const Server = use('Server');
3
4/*
5|--------------------------------------------------------------------------
6| Global Middleware
7|--------------------------------------------------------------------------
8|
9| Global middleware are executed on each http request only when the routes
10| match.
11|
12*/
13const globalMiddleware = [
14 'Adonis/Middleware/BodyParser',
15 'App/Middleware/ConvertEmptyStringsToNull',
16];
17
18/*
19|--------------------------------------------------------------------------
20| Named Middleware
21|--------------------------------------------------------------------------
22|
23| Named middleware is key/value object to conditionally add middleware on
24| specific routes or group of routes.
25|
26| // define
27| {
28| auth: 'Adonis/Middleware/Auth'
29| }
30|
31| // use
32| Route.get().middleware('auth')
33|
34*/
35const namedMiddleware = {
36};
37
38/*
39|--------------------------------------------------------------------------
40| Server Middleware
41|--------------------------------------------------------------------------
42|
43| Server level middleware are executed even when route for a given URL is
44| not registered. Features like `static assets` and `cors` needs better
45| control over request lifecycle.
46|
47*/
48const serverMiddleware = [
49 'Adonis/Middleware/Static',
50];
51
52Server
53 .registerGlobal(globalMiddleware)
54 .registerNamed(namedMiddleware)
55 .use(serverMiddleware);
diff --git a/src/internal-server/start/migrate.js b/src/internal-server/start/migrate.js
new file mode 100644
index 000000000..c27e07bc5
--- /dev/null
+++ b/src/internal-server/start/migrate.js
@@ -0,0 +1,46 @@
1const { ferdiVersion } = require('../../environment');
2
3/**
4 * Migrate server database to work with current Ferdi version
5 */
6const Database = use('Database');
7const User = use('App/Models/User');
8
9const migrateLog = (text) => {
10 console.log('\x1b[36m%s\x1b[0m', 'Ferdi Migration:', '\x1b[0m', text);
11};
12
13module.exports = async () => {
14 migrateLog('🧙‍ Running database migration wizard');
15
16 // Make sure user table exists
17 await Database.raw('CREATE TABLE IF NOT EXISTS `users` (`id` integer not null primary key autoincrement, `settings` text, `created_at` datetime, `updated_at` datetime);');
18
19 const user = await User.find(1);
20 let settings;
21 if (!user) {
22 migrateLog('🎩 Migrating from old Ferdi version as user doesn\'t exist');
23
24 // Create new user
25 await Database.raw('INSERT INTO "users" ("id") VALUES (\'1\');');
26 } else {
27 settings = typeof user.settings === 'string' ? JSON.parse(user.settings) : user.settings;
28 }
29
30 if (!settings || !settings.db_version || settings.db_version !== ferdiVersion) {
31 const srcVersion = settings && settings.db_version ? settings.db_version : '5.4.0-beta.2';
32 migrateLog(`🔮 Migrating table from ${srcVersion} to ${ferdiVersion}`);
33
34 // Migrate database to current Ferdi version
35 // Currently no migrations
36
37 // Update version number in database
38 if (!settings) settings = {};
39 settings.db_version = ferdiVersion;
40 const newUser = await User.find(1); // Fetch user again as we might have only just created it
41 newUser.settings = JSON.stringify(settings);
42 await newUser.save();
43 } else {
44 migrateLog('🔧 Nothing to migrate, already on the newest version');
45 }
46};
diff --git a/src/internal-server/start/routes.js b/src/internal-server/start/routes.js
new file mode 100644
index 000000000..6668f3062
--- /dev/null
+++ b/src/internal-server/start/routes.js
@@ -0,0 +1,86 @@
1/*
2|--------------------------------------------------------------------------
3| Routes
4|--------------------------------------------------------------------------
5|
6*/
7
8/** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */
9const Route = use('Route');
10
11// Run latest database migration
12const migrate = require('./migrate');
13
14migrate();
15
16const OnlyAllowFerdi = async ({ request, response }, next) => {
17 const version = request.header('X-Franz-Version');
18 if (!version) {
19 return response.status(403).redirect('/');
20 }
21
22 await next();
23 return true;
24};
25
26// Health: Returning if all systems function correctly
27Route.get('health', ({
28 response,
29}) => response.send({
30 api: 'success',
31 db: 'success',
32})).middleware(OnlyAllowFerdi);
33
34// API is grouped under '/v1/' route
35Route.group(() => {
36 // User authentification
37 Route.post('auth/signup', 'UserController.signup');
38 Route.post('auth/login', 'UserController.login');
39
40 // User info
41 Route.get('me', 'UserController.me');
42 Route.put('me', 'UserController.updateMe');
43
44 // Service info
45 Route.post('service', 'ServiceController.create');
46 Route.put('service/reorder', 'ServiceController.reorder');
47 Route.put('service/:id', 'ServiceController.edit');
48 Route.delete('service/:id', 'ServiceController.delete');
49 Route.get('me/services', 'ServiceController.list');
50
51 // Recipe store
52 Route.get('recipe', 'ServiceController.list');
53 Route.post('recipes/update', 'ServiceController.update');
54 Route.get('recipes', 'RecipeController.list');
55 Route.get('recipes/download/:recipe', 'RecipeController.download');
56 Route.get('recipes/search', 'RecipeController.search');
57 Route.get('recipes/update', 'StaticController.emptyArray');
58
59 // Workspaces
60 Route.put('workspace/:id', 'WorkspaceController.edit');
61 Route.delete('workspace/:id', 'WorkspaceController.delete');
62 Route.post('workspace', 'WorkspaceController.create');
63 Route.get('workspace', 'WorkspaceController.list');
64
65 // Static responses
66 Route.get('features/:mode?', 'StaticController.features');
67 Route.get('services', 'StaticController.emptyArray');
68 Route.get('news', 'StaticController.emptyArray');
69 Route.get('announcements/:version', 'StaticController.announcement');
70}).prefix('v1').middleware(OnlyAllowFerdi);
71
72Route.group(() => {
73 Route.get('icon/:id', 'ServiceController.icon');
74}).prefix('v1');
75
76// Franz account import
77Route.post('import', 'UserController.import');
78Route.get('import', ({ view }) => view.render('import'));
79
80// Account transfer
81Route.get('export', 'UserController.export');
82Route.post('transfer', 'UserController.importFerdi');
83Route.get('transfer', ({ view }) => view.render('transfer'));
84
85// Index
86Route.get('/', ({ view }) => view.render('index'));