@oondemand/oon-core-back 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oondemand/oon-core-back",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/oondemand/oon-platform.git",
@@ -1,20 +1,22 @@
1
1
  const express = require("express");
2
2
  const axios = require("axios");
3
- const ctx = require("../core/context");
4
3
  const auth = require("../core/middlewares/auth");
4
+ const ctx = require("../core/context");
5
5
  const GenericError = require("../core/errors/GenericError");
6
+ const { asyncHandler, sendResponse } = require("../core/utils/helpers");
6
7
  const {
7
8
  LOGIN_PATH,
8
9
  getBaseUrl,
9
10
  getAppCode,
10
11
  getTimeout,
11
12
  } = require("../core/utils/activationProvider");
12
- const {
13
- ensureInstance,
14
- instanceHeaders,
15
- } = require("../core/utils/instanceActivation");
16
- const { asyncHandler, sendResponse } = require("../core/utils/helpers");
17
13
 
14
+ const DEV_ACTIVATION_PATH = "/integracao/dev-local/ativar-central";
15
+
16
+ /**
17
+ * Rotas de autenticação do Core. Em aplicações member, o login é delegado para
18
+ * a Central de Ativações com o código do app carregado do ambiente do backend.
19
+ */
18
20
  const router = express.Router();
19
21
 
20
22
  function readBasicAuthorization(req) {
@@ -27,23 +29,21 @@ function readBasicAuthorization(req) {
27
29
  return authorization;
28
30
  }
29
31
 
30
- function resolveInstanceHeaders(instance) {
31
- if (instance.ecosystemRole !== "member") return {};
32
-
33
- if (!instance.instanceId) {
34
- if (process.env.NODE_TEST_CONTEXT) return {};
35
-
36
- throw new GenericError(
37
- "Instância member ativa sem identidade do ecossistema.",
38
- { statusCode: 423 },
39
- );
40
- }
41
-
42
- return instanceHeaders(instance);
32
+ function readOptionalAppCode() {
33
+ return String(
34
+ process.env.APP_CODE ||
35
+ process.env.APP_CODIGO ||
36
+ process.env.OON_APP_CODE ||
37
+ process.env.OON_APP_CODIGO ||
38
+ "",
39
+ )
40
+ .trim()
41
+ .toLowerCase();
43
42
  }
44
43
 
45
44
  function translateProviderError(error) {
46
45
  if (error instanceof GenericError) return error;
46
+
47
47
  const timedOut = error.code === "ECONNABORTED";
48
48
  const statusCode = timedOut ? 504 : error.response?.status || 502;
49
49
  const message =
@@ -51,17 +51,13 @@ function translateProviderError(error) {
51
51
  (timedOut
52
52
  ? "A Central de Ativações não respondeu dentro do prazo."
53
53
  : "Não foi possível autenticar o usuário na Central de Ativações.");
54
+
54
55
  return new GenericError(message, { statusCode });
55
56
  }
56
57
 
57
- async function authenticateRoot(req, res, authorization) {
58
+ async function authenticateLocal(req, res, authorization) {
58
59
  const authenticate = ctx.config.auth?.authenticate;
59
- if (typeof authenticate !== "function") {
60
- throw new GenericError(
61
- "A aplicação root não configurou a autenticação local.",
62
- { statusCode: 500 },
63
- );
64
- }
60
+ if (typeof authenticate !== "function") return false;
65
61
 
66
62
  const result = await authenticate({ authorization, req });
67
63
  const statusCode = result?.statusCode || 200;
@@ -69,17 +65,15 @@ async function authenticateRoot(req, res, authorization) {
69
65
 
70
66
  res.set("Cache-Control", "no-store");
71
67
  res.status(statusCode).json(data);
68
+ return true;
72
69
  }
73
70
 
74
71
  router.post(
75
72
  "/autenticar",
76
73
  asyncHandler(async (req, res) => {
77
74
  const authorization = readBasicAuthorization(req);
78
- const instance = await ensureInstance();
79
75
 
80
- if (instance.ecosystemRole === "root") {
81
- return authenticateRoot(req, res, authorization);
82
- }
76
+ if (await authenticateLocal(req, res, authorization)) return;
83
77
 
84
78
  const baseUrl = getBaseUrl(req);
85
79
  const appCode = getAppCode();
@@ -87,7 +81,10 @@ router.post(
87
81
  try {
88
82
  const response = await axios.post(
89
83
  `${baseUrl}${LOGIN_PATH}`,
90
- {},
84
+ {
85
+ codigoApp: appCode,
86
+ codigo: appCode,
87
+ },
91
88
  {
92
89
  timeout: getTimeout(),
93
90
  maxRedirects: 0,
@@ -95,7 +92,46 @@ router.post(
95
92
  Authorization: authorization,
96
93
  "Content-Type": "application/json",
97
94
  "x-app-code": appCode,
98
- ...resolveInstanceHeaders(instance),
95
+ },
96
+ },
97
+ );
98
+
99
+ res.set("Cache-Control", "no-store");
100
+ res.status(response.status).json(response.data);
101
+ } catch (error) {
102
+ throw translateProviderError(error);
103
+ }
104
+ }),
105
+ );
106
+
107
+ router.post(
108
+ "/ativar-dev-local",
109
+ asyncHandler(async (req, res) => {
110
+ const authorization = readBasicAuthorization(req);
111
+ const baseUrl = getBaseUrl(req);
112
+ const appCode = readOptionalAppCode();
113
+
114
+ try {
115
+ const response = await axios.post(
116
+ `${baseUrl}${DEV_ACTIVATION_PATH}`,
117
+ {
118
+ appCode: appCode || req.body?.appCode || req.body?.codigoApp,
119
+ nomeCentral: req.body?.nomeCentral || ctx.config.name,
120
+ appName: req.body?.appName || ctx.config.name,
121
+ appSlug: req.body?.appSlug || ctx.config.slug,
122
+ ambiente: req.body?.ambiente || process.env.NODE_ENV || "development",
123
+ urlPublica: req.body?.urlPublica,
124
+ repositorio: req.body?.repositorio,
125
+ branch: req.body?.branch,
126
+ nomeUsuario: req.body?.nomeUsuario,
127
+ nomeTenant: req.body?.nomeTenant,
128
+ },
129
+ {
130
+ timeout: getTimeout(),
131
+ maxRedirects: 0,
132
+ headers: {
133
+ Authorization: authorization,
134
+ "Content-Type": "application/json",
99
135
  },
100
136
  },
101
137
  );
@@ -7,76 +7,42 @@ const {
7
7
  getAppCode,
8
8
  getTimeout,
9
9
  } = require("../utils/activationProvider");
10
- const {
11
- ensureInstance,
12
- instanceHeaders,
13
- } = require("../utils/instanceActivation");
14
-
15
- function resolveInstanceHeaders(instance) {
16
- if (instance.ecosystemRole !== "member") return {};
17
-
18
- if (!instance.instanceId) {
19
- if (process.env.NODE_TEST_CONTEXT) return {};
20
10
 
21
- const error = new Error(
22
- "Instância member ativa sem identidade do ecossistema.",
23
- );
24
- error.statusCode = 423;
25
- throw error;
26
- }
27
-
28
- return instanceHeaders(instance);
29
- }
30
-
31
- async function defaultVerifyToken(token, context = {}) {
32
- const baseUrl = getBaseUrl(context.req);
11
+ /**
12
+ * Verificador padrão: delega para a Central de Ativações e valida o token no
13
+ * contexto do app configurado no backend por APP_CODE/APP_CODIGO.
14
+ * Pode ser sobrescrito via `central.config.js -> auth.verifyToken`.
15
+ */
16
+ async function defaultVerifyToken(token, { req } = {}) {
17
+ const baseUrl = getBaseUrl(req);
33
18
  const appCode = getAppCode();
34
- const instance = await ensureInstance();
35
19
 
36
- try {
37
- const headers = {
38
- "x-app-code": appCode,
20
+ const response = await axios.get(`${baseUrl}${PERMISSION_PATH}`, {
21
+ timeout: getTimeout(),
22
+ maxRedirects: 0,
23
+ headers: {
39
24
  Authorization: `Bearer ${token}`,
40
- ...resolveInstanceHeaders(instance),
41
- };
42
-
43
- const response = await axios.get(`${baseUrl}${PERMISSION_PATH}`, {
44
- headers,
45
- timeout: getTimeout(),
46
- maxRedirects: 0,
47
- });
48
-
49
- const data = response.data?.usuario;
50
- if (!data) {
51
- const error = new Error(
52
- "Usuário não retornado pela Central de Ativações.",
53
- );
54
- error.statusCode = 502;
55
- throw error;
56
- }
25
+ "x-app-code": appCode,
26
+ },
27
+ });
28
+
29
+ const data = response.data.usuario;
30
+ if (!data) {
31
+ const err = new Error("Usuário não retornado pela Central de Ativações.");
32
+ err.statusCode = 401;
33
+ throw err;
34
+ }
57
35
 
58
- return {
59
- ...data,
60
- tipo:
61
- data.tipo === "master" || data.perfil === "administrador"
62
- ? "admin"
63
- : data.tipo || data.perfil,
64
- };
65
- } catch (error) {
66
- if (error.statusCode) throw error;
36
+ const tipoAcesso =
37
+ data.aplicativo?.tipoAcesso || data.tipoAcesso || data.perfil || data.tipo;
67
38
 
68
- const timedOut = error.code === "ECONNABORTED";
69
- const translated = new Error(
70
- error.response?.data?.message ||
71
- (timedOut
72
- ? "A Central de Ativações não respondeu dentro do prazo."
73
- : "Não foi possível validar a permissão do aplicativo."),
74
- );
75
- translated.statusCode = timedOut
76
- ? 504
77
- : error.response?.status || 502;
78
- throw translated;
79
- }
39
+ return {
40
+ ...data,
41
+ tipo: tipoAcesso === "master" ? "admin" : tipoAcesso,
42
+ perfil: data.perfil || tipoAcesso,
43
+ nome: data.nome,
44
+ email: data.email,
45
+ };
80
46
  }
81
47
 
82
48
  const authMiddleware = async (req, res, next) => {
@@ -102,16 +68,11 @@ const authMiddleware = async (req, res, next) => {
102
68
  req.usuario = usuario;
103
69
  next();
104
70
  } catch (error) {
105
- const statusCode = error.statusCode || error.response?.status || 502;
106
- const message =
107
- statusCode === 403
108
- ? "Usuário sem permissão para acessar este aplicativo."
109
- : statusCode === 401
110
- ? "Token inválido ou expirado."
111
- : error.message ||
112
- "Erro ao validar autenticação e permissão do aplicativo.";
113
-
114
- return Helpers.sendErrorResponse({ res, message, statusCode });
71
+ return Helpers.sendErrorResponse({
72
+ res,
73
+ message: error.message || "Token inválido ou erro na autenticação.",
74
+ statusCode: error.statusCode || error.response?.status || 401,
75
+ });
115
76
  }
116
77
  };
117
78
 
@@ -6,14 +6,18 @@ const PERMISSION_PATH = "/integracao/autenticacao-aplicativos/verificar-permissa
6
6
  function getBaseUrl(req) {
7
7
  const value = process.env.CENTRAL_ATIVACAO_URL || process.env.MEUS_APPS_BACKEND_URL;
8
8
  if (!value) {
9
- throw new GenericError("CENTRAL_ATIVACAO_URL não configurada.", { statusCode: 500 });
9
+ throw new GenericError("CENTRAL_ATIVACAO_URL não configurada.", {
10
+ statusCode: 500,
11
+ });
10
12
  }
11
13
 
12
14
  let parsed;
13
15
  try {
14
16
  parsed = new URL(value);
15
17
  } catch {
16
- throw new GenericError("CENTRAL_ATIVACAO_URL inválida.", { statusCode: 500 });
18
+ throw new GenericError("CENTRAL_ATIVACAO_URL inválida.", {
19
+ statusCode: 500,
20
+ });
17
21
  }
18
22
 
19
23
  const currentHost = String(
@@ -38,12 +42,22 @@ function getBaseUrl(req) {
38
42
  }
39
43
 
40
44
  function getAppCode() {
41
- const value = String(process.env.APP_CODE || process.env.APP_CODIGO || process.env.APP_KEY || "")
45
+ const value = String(
46
+ process.env.APP_CODE ||
47
+ process.env.APP_CODIGO ||
48
+ process.env.OON_APP_CODE ||
49
+ process.env.OON_APP_CODIGO ||
50
+ "",
51
+ )
42
52
  .trim()
43
53
  .toLowerCase();
54
+
44
55
  if (value) return value;
45
56
  if (process.env.NODE_TEST_CONTEXT) return "oon-core-test";
46
- throw new GenericError("APP_CODE não configurada no backend.", { statusCode: 500 });
57
+
58
+ throw new GenericError("APP_CODE não configurada no backend.", {
59
+ statusCode: 500,
60
+ });
47
61
  }
48
62
 
49
63
  function getTimeout() {
@@ -51,4 +65,10 @@ function getTimeout() {
51
65
  return Number.isFinite(value) && value > 0 ? value : 10000;
52
66
  }
53
67
 
54
- module.exports = { LOGIN_PATH, PERMISSION_PATH, getBaseUrl, getAppCode, getTimeout };
68
+ module.exports = {
69
+ LOGIN_PATH,
70
+ PERMISSION_PATH,
71
+ getBaseUrl,
72
+ getAppCode,
73
+ getTimeout,
74
+ };