Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

250 linhas
10 KiB

  1. const fs = require('fs-extra');
  2. const debug = require('debug')('server-connect:setup:routes');
  3. const config = require('./config');
  4. const { map } = require('../core/async');
  5. const { posix, extname } = require('path');
  6. const { cache, serverConnect, templateView } = require('../core/middleware');
  7. const database = require('./database');
  8. const webhooks = require('./webhooks');
  9. module.exports = async function (app) {
  10. app.use((req, res, next) => {
  11. req.fragment = (req.headers['accept'] || '*/*').includes('fragment');
  12. next();
  13. });
  14. if (fs.existsSync('extensions/server_connect/routes')) {
  15. const entries = fs.readdirSync('extensions/server_connect/routes', { withFileTypes: true });
  16. for (let entry of entries) {
  17. if (entry.isFile() && extname(entry.name) == '.js') {
  18. let hook = require(`../../extensions/server_connect/routes/${entry.name}`);
  19. if (hook.before) hook.before(app);
  20. if (hook.handler) hook.handler(app);
  21. debug(`Custom router ${entry.name} loaded`);
  22. }
  23. }
  24. }
  25. if (config.createApiRoutes) {
  26. fs.ensureDirSync('app/api');
  27. createApiRoutes('app/api');
  28. }
  29. if (fs.existsSync('app/config/routes.json')) {
  30. const { routes, layouts } = fs.readJSONSync('app/config/routes.json');
  31. parseRoutes(routes, null);
  32. function parseRoutes(routes, parent) {
  33. for (let route of routes) {
  34. if (!route.path) continue;
  35. createRoute(route, parent);
  36. if (Array.isArray(route.routes)) {
  37. parseRoutes(route.routes, route);
  38. }
  39. }
  40. }
  41. function createRoute({ auth, path, method, redirect, url, page, layout, exec, data, ttl, status, proxy }, parent) {
  42. method = method || 'all';
  43. data = data || {};
  44. if (page) page = page.replace(/^\//, '');
  45. if (layout) layout = layout.replace(/^\//, '');
  46. if (parent && parent.path) path = parent.path + path;
  47. if (auth) {
  48. app.use(path, (req, res, next) => {
  49. if (typeof auth == 'string' && req.session && req.session[auth + 'Id']) {
  50. next();
  51. } else if (typeof auth == 'object' && auth.user) {
  52. const b64auth = (req.headers.authorization || '').split(' ')[1] || '';
  53. const [user, password] = Buffer.from(b64auth, 'base64').toString().split(':');
  54. if (user && password && user === auth.user && password === auth.password) {
  55. next();
  56. } else {
  57. res.set('WWW-Authenticate', 'Basic realm="401"');
  58. res.status(401).json({ error: 'Unauthorized' });
  59. }
  60. } else {
  61. res.status(401).json({ error: 'Unauthorized' });
  62. }
  63. });
  64. }
  65. if (proxy) {
  66. const httpProxy = require('http-proxy');
  67. const proxyServer = httpProxy.createProxyServer(proxy);
  68. app.use(path, (req, res) => {
  69. proxyServer.web(req, res);
  70. });
  71. } else if (redirect) {
  72. app.get(path, (req, res) => res.redirect(status == 302 ? 302 : 301, redirect));
  73. } else if (url) {
  74. app[method](path, (req, res, next) => {
  75. next(parent && !req.fragment ? 'route' : null);
  76. }, (req, res) => {
  77. res.sendFile(url, { root: 'public' })
  78. });
  79. if (parent) {
  80. createRoute({
  81. path,
  82. method: parent.method,
  83. redirect: parent.redirect,
  84. url: parent.url,
  85. page: parent.page,
  86. layout: parent.layout,
  87. exec: parent.exec,
  88. data: parent.data
  89. });
  90. }
  91. } else if (page) {
  92. if (exec) {
  93. if (fs.existsSync(`app/${exec}.json`)) {
  94. let json = fs.readJSONSync(`app/${exec}.json`);
  95. if (json.exec && json.exec.steps) {
  96. json = json.exec.steps;
  97. } else if (json.steps) {
  98. json = json.steps;
  99. }
  100. if (!Array.isArray(json)) {
  101. json = [json];
  102. }
  103. if (layout && layouts && layouts[layout]) {
  104. if (layouts[layout].data) {
  105. data = Object.assign({}, layouts[layout].data, data);
  106. }
  107. if (layouts[layout].exec) {
  108. if (fs.existsSync(`app/${layouts[layout].exec}.json`)) {
  109. let _json = fs.readJSONSync(`app/${layouts[layout].exec}.json`);
  110. if (_json.exec && _json.exec.steps) {
  111. _json = _json.exec.steps;
  112. } else if (_json.steps) {
  113. _json = _json.steps;
  114. }
  115. if (!Array.isArray(_json)) {
  116. _json = [_json];
  117. }
  118. json = _json.concat(json);
  119. } else {
  120. debug(`Route ${path} skipped, "app/${exec}.json" not found`);
  121. return;
  122. }
  123. }
  124. }
  125. app[method](path, (req, res, next) => {
  126. next(parent && !req.fragment ? 'route' : null);
  127. }, cache({ttl}), templateView(layout, page, data, json));
  128. } else {
  129. debug(`Route ${path} skipped, "app/${exec}.json" not found`);
  130. return;
  131. }
  132. } else {
  133. let json = [];
  134. if (layout && layouts && layouts[layout]) {
  135. if (layouts[layout].data) {
  136. data = Object.assign({}, layouts[layout].data, data);
  137. }
  138. if (layouts[layout].exec) {
  139. if (fs.existsSync(`app/${layouts[layout].exec}.json`)) {
  140. let _json = fs.readJSONSync(`app/${layouts[layout].exec}.json`);
  141. if (_json.exec && _json.exec.steps) {
  142. _json = _json.exec.steps;
  143. } else if (_json.steps) {
  144. _json = _json.steps;
  145. }
  146. if (!Array.isArray(_json)) {
  147. _json = [_json];
  148. }
  149. json = _json.concat(json);
  150. } else {
  151. debug(`Route ${path} skipped, "app/${exec}.json" not found`);
  152. return;
  153. }
  154. }
  155. }
  156. app[method](path, (req, res, next) => {
  157. next(parent && !req.fragment ? 'route' : null);
  158. }, cache({ttl}), templateView(layout, page, data, json));
  159. }
  160. if (parent) {
  161. createRoute({
  162. path,
  163. method: parent.method,
  164. redirect: parent.redirect,
  165. url: parent.url,
  166. page: parent.page,
  167. layout: parent.layout,
  168. exec: parent.exec,
  169. data: parent.data
  170. });
  171. }
  172. } else if (exec) {
  173. if (fs.existsSync(`app/${exec}.json`)) {
  174. let json = fs.readJSONSync(`app/${exec}.json`);
  175. app[method](path, cache({ttl}), serverConnect(json));
  176. return;
  177. }
  178. }
  179. }
  180. }
  181. database(app);
  182. webhooks(app);
  183. if (fs.existsSync('extensions/server_connect/routes')) {
  184. const entries = fs.readdirSync('extensions/server_connect/routes', { withFileTypes: true });
  185. for (let entry of entries) {
  186. if (entry.isFile() && extname(entry.name) == '.js') {
  187. let hook = require(`../../extensions/server_connect/routes/${entry.name}`);
  188. if (hook.after) hook.after(app);
  189. debug(`Custom router ${entry.name} loaded`);
  190. }
  191. }
  192. }
  193. function createApiRoutes(dir) {
  194. const entries = fs.readdirSync(dir, { withFileTypes: true });
  195. return map(entries, async (entry) => {
  196. let path = posix.join(dir, entry.name);
  197. if (entry.isFile() && extname(path) == '.json') {
  198. let json = fs.readJSONSync(path);
  199. let routePath = path.replace(/^app/i, '').replace(/.json$/, '(.json)?');
  200. let ttl = (json.settings && json.settings.options && json.settings.options.ttl) ? json.settings.options.ttl : 0;
  201. app.all(routePath, cache({ttl}), serverConnect(json));
  202. debug(`Api route ${routePath} created`);
  203. }
  204. if (entry.isDirectory()) {
  205. return createApiRoutes(path);
  206. }
  207. });
  208. }
  209. };