aboutsummaryrefslogtreecommitdiffstats
path: root/src/internal-server/app/Controllers/Http/RecipeController.js
blob: 48d3ce7e5b9347139924fa8c9d0c302fae367465 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const Recipe = use('App/Models/Recipe');
const Drive = use('Drive');
const { validateAll } = use('Validator');
const Env = use('Env');

const debug = require('../../../../preload-safe-debug')(
  'Ferdium:internalServer:RecipeController',
);
const { LIVE_FERDIUM_API } = require('../../../../config');
const { convertToJSON } = require('../../../../jsUtils');
const { API_VERSION } = require('../../../../environment-remote');

const RECIPES_URL = `${LIVE_FERDIUM_API}/${API_VERSION}/recipes`;

class RecipeController {
  // List official and custom recipes
  async list({ response }) {
    const recipesUrlFetch = await fetch(RECIPES_URL);
    const officialRecipes = convertToJSON(await recipesUrlFetch.text());
    const allRecipes = await Recipe.all();
    const customRecipesArray = allRecipes.rows;
    const customRecipes = customRecipesArray.map(recipe => ({
      id: recipe.recipeId,
      name: recipe.name,
      ...convertToJSON(recipe.data),
    }));

    const recipes = [...officialRecipes, ...customRecipes];

    return response.send(recipes);
  }

  // Search official and custom recipes
  async search({ request, response }) {
    // Validate user input
    const validation = await validateAll(request.all(), {
      needle: 'required',
    });
    if (validation.fails()) {
      return response.status(401).send({
        message: 'Please provide a needle',
        messages: validation.messages(),
        status: 401,
      });
    }

    const needle = request.input('needle');

    // Get results
    let results;

    if (needle === 'ferdium:custom') {
      const allRecipes = await Recipe.all();
      const dbResults = allRecipes.toJSON();
      results = dbResults.map(recipe => ({
        id: recipe.recipeId,
        name: recipe.name,
        ...convertToJSON(recipe.data),
      }));
    } else {
      let remoteResults = [];

      if (Env.get('CONNECT_WITH_FRANZ') === 'true') {
        const recipesUrlFetch = await fetch(
          `${RECIPES_URL}/search?needle=${encodeURIComponent(needle)}`,
        );
        remoteResults = convertToJSON(await recipesUrlFetch.text());
      }

      debug('remoteResults:', remoteResults);

      const recipeQuery = await Recipe.query()
        .where('name', 'LIKE', `%${needle}%`)
        .fetch();
      const localResultsArray = recipeQuery.toJSON();
      const localResults = localResultsArray.map(recipe => ({
        id: recipe.recipeId,
        name: recipe.name,
        ...convertToJSON(recipe.data),
      }));

      debug('localResults:', localResults);

      results = [...localResults, ...(remoteResults || [])];
    }

    return response.send(results);
  }

  // Return an empty array
  update({ response }) {
    return response.send([]);
  }

  async popularRecipes({ response }) {
    const recipesUrlFetch = await fetch(`${RECIPES_URL}/popular`);
    const featuredRecipes = convertToJSON(await recipesUrlFetch.text());
    return response.send(featuredRecipes);
  }

  // Download a recipe
  async download({ response, params }) {
    // Validate user input
    const validation = await validateAll(params, {
      recipe: 'required|accepted',
    });
    if (validation.fails()) {
      return response.status(401).send({
        message: 'Please provide a recipe ID',
        messages: validation.messages(),
        status: 401,
      });
    }

    const service = params.recipe;

    // Check for invalid characters
    if (/\.+/.test(service) || /\/+/.test(service)) {
      return response.send('Invalid recipe name');
    }

    // Check if recipe exists in recipes folder
    if (await Drive.exists(`${service}.tar.gz`)) {
      return response.send(await Drive.get(`${service}.tar.gz`));
    }

    if (Env.get('CONNECT_WITH_FRANZ') === 'true') {
      return response.redirect(`${RECIPES_URL}/download/${service}`);
    }
    return response.status(400).send({
      message: 'Recipe not found',
      code: 'recipe-not-found',
    });
  }
}

module.exports = RecipeController;