diff options
Diffstat (limited to 'src/internal-server/start')
-rw-r--r-- | src/internal-server/start/app.js | 61 | ||||
-rw-r--r-- | src/internal-server/start/kernel.js | 55 | ||||
-rw-r--r-- | src/internal-server/start/migrate.js | 46 | ||||
-rw-r--r-- | src/internal-server/start/routes.js | 86 |
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 | */ | ||
11 | const 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 | */ | ||
31 | const 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 | */ | ||
47 | const aliases = {}; | ||
48 | |||
49 | /* | ||
50 | |-------------------------------------------------------------------------- | ||
51 | | Commands | ||
52 | |-------------------------------------------------------------------------- | ||
53 | | | ||
54 | | Here you store ace commands for your package | ||
55 | | | ||
56 | */ | ||
57 | const commands = []; | ||
58 | |||
59 | module.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')} */ | ||
2 | const 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 | */ | ||
13 | const 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 | */ | ||
35 | const 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 | */ | ||
48 | const serverMiddleware = [ | ||
49 | 'Adonis/Middleware/Static', | ||
50 | ]; | ||
51 | |||
52 | Server | ||
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 @@ | |||
1 | const { ferdiVersion } = require('../../environment'); | ||
2 | |||
3 | /** | ||
4 | * Migrate server database to work with current Ferdi version | ||
5 | */ | ||
6 | const Database = use('Database'); | ||
7 | const User = use('App/Models/User'); | ||
8 | |||
9 | const migrateLog = (text) => { | ||
10 | console.log('\x1b[36m%s\x1b[0m', 'Ferdi Migration:', '\x1b[0m', text); | ||
11 | }; | ||
12 | |||
13 | module.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')} */ | ||
9 | const Route = use('Route'); | ||
10 | |||
11 | // Run latest database migration | ||
12 | const migrate = require('./migrate'); | ||
13 | |||
14 | migrate(); | ||
15 | |||
16 | const 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 | ||
27 | Route.get('health', ({ | ||
28 | response, | ||
29 | }) => response.send({ | ||
30 | api: 'success', | ||
31 | db: 'success', | ||
32 | })).middleware(OnlyAllowFerdi); | ||
33 | |||
34 | // API is grouped under '/v1/' route | ||
35 | Route.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 | |||
72 | Route.group(() => { | ||
73 | Route.get('icon/:id', 'ServiceController.icon'); | ||
74 | }).prefix('v1'); | ||
75 | |||
76 | // Franz account import | ||
77 | Route.post('import', 'UserController.import'); | ||
78 | Route.get('import', ({ view }) => view.render('import')); | ||
79 | |||
80 | // Account transfer | ||
81 | Route.get('export', 'UserController.export'); | ||
82 | Route.post('transfer', 'UserController.importFerdi'); | ||
83 | Route.get('transfer', ({ view }) => view.render('transfer')); | ||
84 | |||
85 | // Index | ||
86 | Route.get('/', ({ view }) => view.render('index')); | ||