corebasic 1.0.103 → 1.0.105
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/libs/auth.js +11 -7
- package/libs/dip.js +9 -7
- package/libs/elabase.js +34 -4
- package/libs/features.js +5 -5
- package/libs/privileges.js +14 -10
- package/package.json +1 -1
package/libs/auth.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import axios from 'axios'
|
|
2
2
|
import otpGenerator from 'otp-generator'
|
|
3
3
|
|
|
4
|
-
import * as
|
|
4
|
+
import * as Dip from './dip.js'
|
|
5
5
|
import * as Utils from './utils.js'
|
|
6
6
|
import * as Session from './session.js'
|
|
7
7
|
|
|
@@ -34,6 +34,8 @@ export const start = (app, successCallback) => {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
async function attemptLogin(req, res) {
|
|
37
|
+
let meta = {company: "GLOBAL", outlet: "GLOBAL"}
|
|
38
|
+
|
|
37
39
|
let expiry = 300000
|
|
38
40
|
let phone = req.body.phone.trim()
|
|
39
41
|
let time = new Date().getTime()
|
|
@@ -45,9 +47,9 @@ async function attemptLogin(req, res) {
|
|
|
45
47
|
throw { ...errMessage, mode: otpValid ? 'verify' : 'login', info: "Invalid Client ID" }
|
|
46
48
|
|
|
47
49
|
if (otpValid) { // verify login
|
|
48
|
-
let res = await
|
|
50
|
+
let res = await Dip.query(meta, collection, { _id: phone, otp: req.body.otp, clientId, time: { $gt: time - expiry } })
|
|
49
51
|
if (res.length) {
|
|
50
|
-
try {await
|
|
52
|
+
try {await Dip.update(meta, collection, { _id: phone }, { $set: { otp: '', clientId: '' } }) } catch (err) { throw {...errMessage, mode: 'verify', info: 'Cleanup Failed'} }
|
|
51
53
|
return {...res[0], mode: 'verify', success: true, userId: res[0].userId, phone: res[0]._id}
|
|
52
54
|
}
|
|
53
55
|
throw {...errMessage, mode: 'verify', info: "Invalid/Expired OTP"}
|
|
@@ -57,8 +59,9 @@ async function attemptLogin(req, res) {
|
|
|
57
59
|
let userId = req.body.userId ?? Utils.uid()
|
|
58
60
|
let now = Utils.now().toISOString()
|
|
59
61
|
let data = req.body.data ?? {}
|
|
60
|
-
let
|
|
61
|
-
await
|
|
62
|
+
let info = { clientId, created: now, updated: now, ...data}
|
|
63
|
+
await Dip.update(meta, collection, { _id: phone }, { $set: { otp, clientId, time, updated: now }, $setOnInsert: { _id: phone, otp, time, userId, ...info } }, { upsert: true })
|
|
64
|
+
|
|
62
65
|
return {mode: 'login', success: true, userId, expiry, phone}
|
|
63
66
|
}
|
|
64
67
|
throw {...errMessage, mode: 'login', info: 'Generating Info Failed'}
|
|
@@ -85,9 +88,10 @@ async function sendOtp(phone, otp, app) {
|
|
|
85
88
|
|
|
86
89
|
// Usage
|
|
87
90
|
// Auth.validate((req) => ["Phone1", "Phone2"].includes(req.body.phone.trim()))
|
|
88
|
-
// Auth.start(app, async (req, res, data) => {
|
|
91
|
+
// Auth.start(app, async (req, res, data) => {
|
|
89
92
|
// try {
|
|
90
|
-
//
|
|
93
|
+
// let meta = {company: "GLOBAL", outlet: "GLOBAL"}
|
|
94
|
+
// await Dip.insert(meta, "users", { }, "asdsds")
|
|
91
95
|
// await Kafka.send("users", {event: "userLogin", ...data, time: Utils.now()})
|
|
92
96
|
// res.json(data)
|
|
93
97
|
// } catch {
|
package/libs/dip.js
CHANGED
|
@@ -18,28 +18,30 @@ export let config = Elabase.config
|
|
|
18
18
|
export const IdempotentDip = () => {
|
|
19
19
|
return {
|
|
20
20
|
txn: '',
|
|
21
|
-
|
|
21
|
+
meta: undefined,
|
|
22
|
+
new: (async function (meta, txn, blank) {
|
|
22
23
|
this.txn = txn
|
|
23
|
-
|
|
24
|
+
this.meta = meta
|
|
25
|
+
return blank ? this : (await Elabase.query(this.meta, "txns",{_id: this.txn}).length ? false : this)
|
|
24
26
|
}),
|
|
25
27
|
insert: (async function (collection, query, data) {
|
|
26
|
-
await Elabase.update(collection, query, { $setOnInsert: data }, {upsert: true})
|
|
28
|
+
await Elabase.update(this.meta, collection, query, { $setOnInsert: data }, {upsert: true})
|
|
27
29
|
}),
|
|
28
30
|
update: (async function (collection, query, data, rollback) {
|
|
29
31
|
let token = { [this.txn]: true }
|
|
30
32
|
let idempotent = { [this.txn]: { $exists: rollback ?? false } }
|
|
31
|
-
let result = await Elabase.update(collection, {...query, ...idempotent}, {...data, $setOnInsert: undefined, $set: {...(data.$set ?? {}), ...token} })
|
|
32
|
-
return result.count ? true : await Elabase.query(collection, {...query, ...idempotent}).length
|
|
33
|
+
let result = await Elabase.update(this.meta, collection, {...query, ...idempotent}, {...data, $setOnInsert: undefined, $set: {...(data.$set ?? {}), ...token} })
|
|
34
|
+
return result.count ? true : await Elabase.query(this.meta, collection, {...query, ...idempotent}).length
|
|
33
35
|
}),
|
|
34
36
|
upsert: (async function (collection, query, data, rollback) {
|
|
35
37
|
await this.insert(collection, query, data.$setOnInsert)
|
|
36
38
|
return await this.update(collection, query, data, rollback)
|
|
37
39
|
}),
|
|
38
40
|
cleanup: (async function (collection, query) {
|
|
39
|
-
await Elabase.update(collection, query, { $unset: { [this.txn]: true } })
|
|
41
|
+
await Elabase.update(this.meta, collection, query, { $unset: { [this.txn]: true } })
|
|
40
42
|
}),
|
|
41
43
|
finish: (async function () {
|
|
42
|
-
return await Elabase.update("txns",{_id: this.txn}, {}, {upsert: true})
|
|
44
|
+
return await Elabase.update(this.meta, "txns",{_id: this.txn}, {}, {upsert: true})
|
|
43
45
|
})
|
|
44
46
|
}
|
|
45
47
|
}
|
package/libs/elabase.js
CHANGED
|
@@ -83,7 +83,15 @@ export function transactionCommit(arg) {
|
|
|
83
83
|
})
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export const insert = async (collection, value, _id) => {
|
|
86
|
+
export const insert = async (meta, collection, value, _id) => {
|
|
87
|
+
// Multi Company Support
|
|
88
|
+
collection = `${meta.company}.${collection}`
|
|
89
|
+
if (meta.company !== "GLOBAL") {
|
|
90
|
+
if (typeof value === "object" && !Array.isArray(value))
|
|
91
|
+
value.company = meta.company
|
|
92
|
+
}
|
|
93
|
+
// ---------------------
|
|
94
|
+
|
|
87
95
|
var arg = {
|
|
88
96
|
collection: collection,
|
|
89
97
|
insert: value
|
|
@@ -104,7 +112,14 @@ export const insert = async (collection, value, _id) => {
|
|
|
104
112
|
})
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
export const query = async (collection, query, options) => {
|
|
115
|
+
export const query = async (meta, collection, query, options) => {
|
|
116
|
+
// Multi Company Support
|
|
117
|
+
collection = `${meta.company}.${collection}`
|
|
118
|
+
if (meta.company !== "GLOBAL")
|
|
119
|
+
query.company = meta.company
|
|
120
|
+
// ---------------------
|
|
121
|
+
|
|
122
|
+
|
|
108
123
|
var arg = {
|
|
109
124
|
collection: collection,
|
|
110
125
|
query: query,
|
|
@@ -137,7 +152,16 @@ function collectionArray(col) {
|
|
|
137
152
|
}
|
|
138
153
|
|
|
139
154
|
|
|
140
|
-
export const update = async (collection, query, update, options) => {
|
|
155
|
+
export const update = async (meta, collection, query, update, options) => {
|
|
156
|
+
// Multi Company Support
|
|
157
|
+
collection = `${meta.company}.${collection}`
|
|
158
|
+
if (meta.company !== "GLOBAL") {
|
|
159
|
+
query.company = meta.company
|
|
160
|
+
if (update?.$setOnInsert)
|
|
161
|
+
update.$setOnInsert.company = meta.company
|
|
162
|
+
}
|
|
163
|
+
// ---------------------
|
|
164
|
+
|
|
141
165
|
var arg = {
|
|
142
166
|
collection: collection,
|
|
143
167
|
query: query,
|
|
@@ -157,7 +181,13 @@ export const update = async (collection, query, update, options) => {
|
|
|
157
181
|
})
|
|
158
182
|
}
|
|
159
183
|
|
|
160
|
-
export const remove = async (collection, query) => {
|
|
184
|
+
export const remove = async (meta, collection, query) => {
|
|
185
|
+
// Multi Company Support
|
|
186
|
+
collection = `${meta.company}.${collection}`
|
|
187
|
+
if (meta.company !== "GLOBAL")
|
|
188
|
+
query.company = meta.company
|
|
189
|
+
// ---------------------
|
|
190
|
+
|
|
161
191
|
var arg = {
|
|
162
192
|
collection: collection,
|
|
163
193
|
query: query,
|
package/libs/features.js
CHANGED
|
@@ -166,9 +166,9 @@ export const start = async (app, url, file) => {
|
|
|
166
166
|
topic = topic.replace(/^.*Features./,'')
|
|
167
167
|
while (true) {
|
|
168
168
|
try {
|
|
169
|
-
await Dip.update(`users.txns.${message.user}`, {_id: message.txn}, { $setOnInsert: { user: message.user, feature: message.feature, date: message.date, created: message.date, updated: message.date, status: "Queued" } }, {upsert: true}) // Can always update the status later
|
|
169
|
+
await Dip.update(message.meta, `users.txns.${message.user}`, {_id: message.txn}, { $setOnInsert: { user: message.user, feature: message.feature, date: message.date, created: message.date, updated: message.date, status: "Queued" } }, {upsert: true}) // Can always update the status later
|
|
170
170
|
await features[message.feature].handler(topic, message)
|
|
171
|
-
await Dip.insert("Features.txns", {_id: message.txn, status: "Processed"})
|
|
171
|
+
await Dip.insert(message.meta, "Features.txns", {_id: message.txn, status: "Processed"})
|
|
172
172
|
break
|
|
173
173
|
} catch {
|
|
174
174
|
console.warn(`Feature: ${message.feature}, error in executing handler during Kafka.receive(topic: ${topic})`)
|
|
@@ -179,9 +179,9 @@ export const start = async (app, url, file) => {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
// Transaction status api
|
|
182
|
-
app.get('/transactions/:id', async (req, res) => {
|
|
182
|
+
app.get('/transactions/:id', async (req, res) => { // Front end calls this as a regular feature call. so `req.meta` exists
|
|
183
183
|
try {
|
|
184
|
-
let items = await Dip.query("Features.txns", {_id: req.params.id})
|
|
184
|
+
let items = await Dip.query(req.meta, "Features.txns", {_id: req.params.id})
|
|
185
185
|
if (items.length)
|
|
186
186
|
res.json({ data: { ...items[0], txn: items._id } })
|
|
187
187
|
else
|
|
@@ -192,7 +192,7 @@ export const start = async (app, url, file) => {
|
|
|
192
192
|
})
|
|
193
193
|
app.get('/users/:id/transactions', async (req, res) => {
|
|
194
194
|
try {
|
|
195
|
-
res.json({ data: await Dip.query(`users.txns.${req.params.id}`, {}, { $orderby: { date: -1 } }) })
|
|
195
|
+
res.json({ data: await Dip.query(req.meta, `users.txns.${req.params.id}`, {}, { $orderby: { date: -1 } }) })
|
|
196
196
|
} catch {
|
|
197
197
|
res.status(500).json({ message: "Failed to retreive data" })
|
|
198
198
|
}
|
package/libs/privileges.js
CHANGED
|
@@ -21,9 +21,10 @@ let PRIVILEGES_CACHE = {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
const get = async (company) => {
|
|
25
25
|
PRIVILEGES_CACHE[company] = {}
|
|
26
|
-
let
|
|
26
|
+
let meta = {company, outlet: "GLOBAL"}
|
|
27
|
+
let privileges = await Dip.query(meta, "privileges", { })
|
|
27
28
|
privileges.forEach(privilege => PRIVILEGES_CACHE[company][privilege.name] = privilege)
|
|
28
29
|
|
|
29
30
|
// Format
|
|
@@ -34,7 +35,8 @@ export const get = async (company) => {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export const start = async () => {
|
|
37
|
-
let
|
|
38
|
+
let meta = {company: "GLOBAL", outlet: "GLOBAL"}
|
|
39
|
+
let companies = await Dip.query(meta, "companies", { })
|
|
38
40
|
for (let company of companies)
|
|
39
41
|
await get(company._id)
|
|
40
42
|
}
|
|
@@ -63,25 +65,27 @@ function rolesToFeatures(company, roles) {
|
|
|
63
65
|
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
const getAllowedFeatures = (company, roles) => {
|
|
67
69
|
return [...new Set(rolesToFeatures(company, roles))]
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
let roles = await getRoles(company, user)
|
|
72
|
+
const check = async (company, user, feature, req) => {
|
|
73
|
+
let roles = await getRoles(company, user, req)
|
|
72
74
|
return roles.includes(feature)
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export const checkRequest = async (req) => {
|
|
76
|
-
|
|
78
|
+
let meta = {...req.body, data: undefined}
|
|
79
|
+
req.meta = meta
|
|
80
|
+
return await check(req.body.company, req.body.user, req.body.feature, req)
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
|
|
80
84
|
|
|
81
85
|
|
|
82
|
-
const getRoles = async (company, user) => {
|
|
83
|
-
let staff = (await Dip.query("staff", { user: user }))[0]
|
|
84
|
-
let roles = (await Dip.query("privileges.staff", { _id: staff._id }))[0].items.map(item => item._id)
|
|
86
|
+
const getRoles = async (company, user, req) => {
|
|
87
|
+
let staff = (await Dip.query(req.meta, "staff", { user: user }))[0]
|
|
88
|
+
let roles = (await Dip.query(req.meta, "privileges.staff", { _id: staff._id }))[0].items.map(item => item._id)
|
|
85
89
|
return getAllowedFeatures(company, roles)
|
|
86
90
|
}
|
|
87
91
|
|