@go-mailer/jarvis 10.5.1 → 10.7.0

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.
@@ -3,6 +3,24 @@ const Env = require('../env')
3
3
  const BASE_URI = Env.fetch('GO_FLAGS_URI', true)
4
4
  const API_KEY = Env.fetch('GO_FLAGS_KEY', true)
5
5
 
6
+ const sendLog = async ({ environment, service, type, message, log_data }) => {
7
+ await axios.post(
8
+ `${BASE_URI}/api/v1/logs`,
9
+ {
10
+ environment,
11
+ type,
12
+ message,
13
+ service,
14
+ metadata: log_data
15
+ },
16
+ {
17
+ headers: {
18
+ authorization: `Bearer ${API_KEY}`
19
+ }
20
+ }
21
+ )
22
+ }
23
+
6
24
  const verifyFeatureFlag = async (flag_name, criteria = {}, environment = '') => {
7
25
  const { error, payload } = (
8
26
  await axios.post(
@@ -24,4 +42,4 @@ const verifyFeatureFlag = async (flag_name, criteria = {}, environment = '') =>
24
42
  return payload.is_permitted
25
43
  }
26
44
 
27
- module.exports = { verifyFeatureFlag }
45
+ module.exports = { sendLog, verifyFeatureFlag }
@@ -32,6 +32,28 @@ const fetchTenants = async (query = '') => {
32
32
  return { tenants, size: meta?.size || 0 }
33
33
  }
34
34
 
35
+ const refreshToken = async (data = {}, query = '', tries = 0) => {
36
+ try {
37
+ const { data: response } = await axios.post(
38
+ `${IAM_URI}/guests/token/refresh?${query}`,
39
+ { ...data },
40
+ {
41
+ headers: {
42
+ authorization: `Bearer ${DEFAULT_TOKEN}`
43
+ }
44
+ }
45
+ )
46
+
47
+ const { error, payload } = response
48
+ if (error) throw new Error(error)
49
+
50
+ return payload
51
+ } catch (e) {
52
+ if (tries < 3) return await refreshToken(data, query, tries + 1)
53
+ return null
54
+ }
55
+ }
56
+
35
57
  const verifyAPIKey = async (key) => {
36
58
  const { error, payload } = (
37
59
  await axios.get(`${API_SERVICE_URI}/keys/verify/${key}`, {
@@ -68,4 +90,4 @@ const verifyFeatureFlag = async (flag_name, criteria = {}) => {
68
90
  return payload.is_permitted
69
91
  }
70
92
 
71
- module.exports = { checkAuthority, fetchTenants, verifyAPIKey, verifyFeatureFlag }
93
+ module.exports = { checkAuthority, fetchTenants, refreshToken, verifyAPIKey, verifyFeatureFlag }
@@ -10,8 +10,7 @@ const geoip = require('geoip-lite')
10
10
  const Env = require('../env')
11
11
  const Errors = require('./errors')
12
12
  const { ProcessLogger } = require('./logger')
13
- const { checkAuthority, verifyAPIKey } = require('../clients/iam')
14
- const { localCache } = require('../redis/cache')
13
+ const { verifyAPIKey } = require('../clients/iam')
15
14
  const authLogger = new ProcessLogger('Authenticator')
16
15
 
17
16
  // helpers
@@ -98,10 +97,18 @@ const authenticateUser = async (request, response, next) => {
98
97
  return next()
99
98
  }
100
99
 
101
- const { id: user_id, is_admin, tenant_id } = await jwt.verify(token, SECRET, { issuer: ISSUER })
100
+ const {
101
+ id: user_id,
102
+ is_admin,
103
+ tenant_id,
104
+ permissions,
105
+ permission_expires_at
106
+ } = await jwt.verify(token, SECRET, { issuer: ISSUER })
102
107
  request.is_admin = !!is_admin
103
108
  request.user_id = is_admin ? extractId(request, 'user_id') : user_id
104
109
  request.tenant_id = is_admin ? extractId(request, 'tenant_id') : tenant_id
110
+ request.permissions = permissions
111
+ request.permission_expires_at = permission_expires_at
105
112
 
106
113
  next()
107
114
  } catch (e) {
@@ -113,15 +120,17 @@ const authenticateUser = async (request, response, next) => {
113
120
  const authorizeUser = ({ action, resource }) => {
114
121
  return async (request, response, next) => {
115
122
  try {
116
- const { is_admin, is_service_request, tenant_id, user_id } = request
123
+ const { is_admin, is_service_request, permissions, permission_expires_at } = request
117
124
  if (is_admin || is_service_request) return next()
118
125
 
119
- const key = `${resource}:${action}:${tenant_id}:${user_id}`
120
- const has_authority = localCache.get_item(key)
121
- if (has_authority == null) {
122
- const is_permitted = await checkAuthority({ action, resource, tenant_id, user_id })
123
- localCache.add_item(key, is_permitted, 15 * 60)
124
- } else if (has_authority === false) {
126
+ if (!permissions || !permission_expires_at) throw new Error('Unauthorized')
127
+ if (Date.now() > permission_expires_at) {
128
+ throw new Error('')
129
+ }
130
+
131
+ const is_superadmin = Object.keys(permissions)[0].includes('*')
132
+ const is_permitted = permissions[`${resource}:${action}`]
133
+ if (!is_superadmin && !is_permitted) {
125
134
  throw new Error('Unauthorized')
126
135
  }
127
136
 
@@ -2,8 +2,11 @@
2
2
  * @author Oguntuberu Nathan O. <nateoguns.work@gmail.com>
3
3
  **/
4
4
 
5
+ const { sendLog } = require('../clients/go-flags')
5
6
  const Env = require('../env')
6
7
  const { randomUUID } = require('crypto')
8
+ const app_name = Env.fetch('APP_NAME', true)
9
+ const env = Env.fetch('NODE_ENV', true)
7
10
 
8
11
  function hashLogData (log = {}) {
9
12
  const hashed = JSON.stringify(log).replace(/\w+@/gi, '************')
@@ -11,7 +14,6 @@ function hashLogData (log = {}) {
11
14
  }
12
15
 
13
16
  function RequestLogger () {
14
- const app_name = Env.fetch('APP_NAME', true)
15
17
  return (request, response, next) => {
16
18
  if (!request.request_id) request.request_id = randomUUID()
17
19
 
@@ -54,14 +56,14 @@ function RequestLogger () {
54
56
  }
55
57
 
56
58
  log.error = payload ? payload.error : statusMessage
57
- // if (error) {
58
- // log.error = error;
59
- // logtail.error(pathname, hashLogData(log));
60
- // } else {
61
- // logtail.info(pathname, hashLogData(log));
62
- // }
59
+ let log_type = 'info'
60
+ let message = 'Success'
61
+ if (log.error) {
62
+ log_type = 'error'
63
+ message = log.error
64
+ sendLog({ type: log_type, service: app_name, environment: env, message: message, log_data: log })
65
+ }
63
66
 
64
- // logtail.flush();
65
67
  console.log(pathname, hashLogData({ status_code: log.status_code, request_id: log.request_id }))
66
68
  })
67
69
 
@@ -75,14 +77,13 @@ class ProcessLogger {
75
77
  }
76
78
 
77
79
  error (error, method = 'unspecified_method', params = {}) {
78
- // logtail.error(`${this.service}:${method}:${error.message}`, hashLogData({
79
- // app_name: Env.fetch("APP_NAME", true),
80
- // type: "process",
81
- // message: error.message,
82
- // trace: error.stack,
83
- // params,
84
- // }));
85
- // logtail.flush();
80
+ sendLog({
81
+ type: 'error',
82
+ service: app_name,
83
+ environment: env,
84
+ message: error.message,
85
+ log_data: { ...params, stack: error.stack }
86
+ })
86
87
  console.log(`${this.service}:${method}:${error.message}`, params, error.stack)
87
88
  }
88
89
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-mailer/jarvis",
3
- "version": "10.5.1",
3
+ "version": "10.7.0",
4
4
  "main": "index.js",
5
5
  "repository": "git@github.com:go-mailer-ltd/jarvis-node.git",
6
6
  "author": "Nathan Oguntuberu <nateoguns.work@gmail.com>",