@everneed/worker 1.2.0 → 2.0.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.
- package/index.js +1 -1
- package/package.json +1 -1
- package/worker/rabbitmq.js +400 -99
package/index.js
CHANGED
|
@@ -89,6 +89,6 @@ import pseudoEnv from "./pseudoenv.js"
|
|
|
89
89
|
|
|
90
90
|
export { rabbitmq } // preserve seperate-dir for example
|
|
91
91
|
export { postgresInstance as postgres }
|
|
92
|
-
|
|
92
|
+
export { mongooseInstance as mongoose }
|
|
93
93
|
export { redisInstance as redis }
|
|
94
94
|
export { socketioInstance as socketio }
|
package/package.json
CHANGED
package/worker/rabbitmq.js
CHANGED
|
@@ -10,6 +10,178 @@ import { redis } from "@everneed/worker"
|
|
|
10
10
|
import { ResponseCode } from "@everneed/responsecode"
|
|
11
11
|
import { pipe, switchPourStr, randomStr } from "@everneed/helper"
|
|
12
12
|
|
|
13
|
+
class VersionManager{
|
|
14
|
+
#currentVer
|
|
15
|
+
#deprecated
|
|
16
|
+
#configPath = null
|
|
17
|
+
#endpointMap
|
|
18
|
+
|
|
19
|
+
// 🗑️
|
|
20
|
+
#existingBucket = []
|
|
21
|
+
#loadedBucket = []
|
|
22
|
+
|
|
23
|
+
constructor(){
|
|
24
|
+
this.init()
|
|
25
|
+
this.#load()
|
|
26
|
+
}
|
|
27
|
+
init(){
|
|
28
|
+
this.#load()
|
|
29
|
+
}
|
|
30
|
+
config(configPath){
|
|
31
|
+
this.#configPath = path.join("../../..", configPath)
|
|
32
|
+
|
|
33
|
+
/* Re-init */
|
|
34
|
+
this.init()
|
|
35
|
+
}
|
|
36
|
+
#clean(){
|
|
37
|
+
this.#currentVer = null
|
|
38
|
+
this.#configPath = null
|
|
39
|
+
this.#endpointMap = {}
|
|
40
|
+
this.#existingBucket = []
|
|
41
|
+
this.#loadedBucket = []
|
|
42
|
+
}
|
|
43
|
+
#load(){
|
|
44
|
+
// json into endpointMaps
|
|
45
|
+
let json
|
|
46
|
+
if(!this.#configPath){
|
|
47
|
+
try{
|
|
48
|
+
// json = require("../../config/versionmap.json")
|
|
49
|
+
json = fs.readFileSync(path.join(process.cwd(), "/config/versionmap.json"))
|
|
50
|
+
}
|
|
51
|
+
catch(err){
|
|
52
|
+
json = `{"/endpoint/one":{"latest": 1, "map":{"1":1}}}`
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else{
|
|
56
|
+
json = fs.readFileSync(path.resolve(this.#configPath))
|
|
57
|
+
const fs = require("fs")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const config = pipe(json)
|
|
61
|
+
.then(json=> JSON.parse(json))
|
|
62
|
+
.result
|
|
63
|
+
this.#endpointMap = config.endpoint
|
|
64
|
+
this.#currentVer = config.apiVer
|
|
65
|
+
this.#deprecated = config.deprecatedVer
|
|
66
|
+
}
|
|
67
|
+
async update(){
|
|
68
|
+
// Define new version
|
|
69
|
+
const newVer = this.#currentVer+1
|
|
70
|
+
// Load all existing running API and stage them
|
|
71
|
+
// in existingBucket
|
|
72
|
+
const files = fs.readdirSync(`./src/mq-gateway`)
|
|
73
|
+
for(const file of files){
|
|
74
|
+
const module = file.replace(/.js|.ts/g, ``).toLowerCase()
|
|
75
|
+
const functs = await import(`file://${path.join(process.cwd(), `/src/mq-gateway/${file}`)}`)
|
|
76
|
+
|
|
77
|
+
for(const funct in functs.default){
|
|
78
|
+
for(const ver in functs.default[funct].function){
|
|
79
|
+
this.#existingBucket.push(`/${pseudoEnv.process.env.SVC_NAME}/${module}/${funct}/${ver}`)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Prep irregular changes and unchanges 🔪🌽🍍🥕
|
|
85
|
+
// into more consumable iterable form
|
|
86
|
+
// will output the elements from existing bucket that are not in the loaded bucket
|
|
87
|
+
const addition = this.#existingBucket.filter(x => !this.#loadedBucket.includes(x))
|
|
88
|
+
const updation = pipe(addition)
|
|
89
|
+
.then(addition=>{
|
|
90
|
+
return {
|
|
91
|
+
addition: addition.map(fullEndpoint=> fullEndpoint.split(/\/v([0-9]+)$/, 2)[0]),
|
|
92
|
+
all: this.#existingBucket.map(fullEndpoint=> fullEndpoint.split(/\/v([0-9]+)$/, 2)[0])
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
.then(({addition, all})=> new Set(all).difference(new Set(addition)))
|
|
96
|
+
.then(set=> [...set])
|
|
97
|
+
.result
|
|
98
|
+
|
|
99
|
+
// Process to then stash result to head variable 🥣
|
|
100
|
+
for(const endpoint of addition){
|
|
101
|
+
// "/endpoint/one/v1" -> [/endpoint/one, 1]
|
|
102
|
+
const [pureEndpoint, versionInt] = endpoint.split(/\/v([0-9]+)$/, 2)
|
|
103
|
+
|
|
104
|
+
// new endpoint
|
|
105
|
+
if(!this.#endpointMap[pureEndpoint]){
|
|
106
|
+
this.#endpointMap[pureEndpoint] = {
|
|
107
|
+
latest: 1,
|
|
108
|
+
map: {}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.#endpointMap[pureEndpoint]["map"][`v${newVer}`] = 1
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.#endpointMap[pureEndpoint].latest = Number(versionInt)
|
|
115
|
+
this.#endpointMap[pureEndpoint].map[`v${newVer}`] = Number(versionInt)
|
|
116
|
+
// /pure/endpoint:{
|
|
117
|
+
// latest: (2), <--- updated
|
|
118
|
+
// map:{
|
|
119
|
+
// v1: 1,
|
|
120
|
+
// v2: 1,
|
|
121
|
+
// v3: 2 <-- addition
|
|
122
|
+
// }
|
|
123
|
+
// }
|
|
124
|
+
}
|
|
125
|
+
for(const endpoint in updation){
|
|
126
|
+
this.#endpointMap[endpoint].map[`v${newVer}`] = this.#endpointMap[endpoint].latest
|
|
127
|
+
// /pure/endpoint:{
|
|
128
|
+
// latest: 1,
|
|
129
|
+
// map:{
|
|
130
|
+
// v1: 1,
|
|
131
|
+
// v2: 1,
|
|
132
|
+
// v3: 1 <-- updated
|
|
133
|
+
// }
|
|
134
|
+
// }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Save head variable into config file (.json)
|
|
138
|
+
const json = JSON.stringify({
|
|
139
|
+
apiVer: newVer,
|
|
140
|
+
lastUpdate: moment().utc().format(),
|
|
141
|
+
endpoint: this.#endpointMap
|
|
142
|
+
}, null, 4)
|
|
143
|
+
if(!this.#configPath){
|
|
144
|
+
try{
|
|
145
|
+
fs.writeFileSync(path.join(process.cwd(), "/config/versionmap.json"), json)
|
|
146
|
+
}
|
|
147
|
+
catch(err){
|
|
148
|
+
console.log(err)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else{
|
|
152
|
+
fs.writeFileSync(path.resolve(__dirname, this.#configPath), json)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// re-load
|
|
156
|
+
this.#clean()
|
|
157
|
+
this.#load()
|
|
158
|
+
}
|
|
159
|
+
allVersion(endpoint){
|
|
160
|
+
// returns array of available version map
|
|
161
|
+
// in respecting order (index 0 should be null)
|
|
162
|
+
// Array due to be iterated nature
|
|
163
|
+
|
|
164
|
+
const result = [null]
|
|
165
|
+
|
|
166
|
+
for(const majorVer in this.#endpointMap[endpoint].map){
|
|
167
|
+
result[majorVer] = this.#endpointMap[endpoint].map[majorVer] // major = individual
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return result // [null, individual ver, individual ver]
|
|
171
|
+
}
|
|
172
|
+
trueVersion({endpoint, version}){
|
|
173
|
+
return this.#endpointMap[endpoint].map[`v${version}`]
|
|
174
|
+
}
|
|
175
|
+
latestVersion(){
|
|
176
|
+
return this.#currentVer
|
|
177
|
+
}
|
|
178
|
+
deprecatedVersion(){
|
|
179
|
+
return this.#deprecated
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const version = new VersionManager()
|
|
183
|
+
version.init()
|
|
184
|
+
|
|
13
185
|
export default {
|
|
14
186
|
config: function(object){
|
|
15
187
|
// config({
|
|
@@ -55,73 +227,106 @@ export default {
|
|
|
55
227
|
const main = await import(`file://${path.join(process.cwd(), `/src/mq-gateway/${moduleSpace}`)}.js`)
|
|
56
228
|
// const main = await import(`#@/mq-gateway/${moduleSpace}.js`)
|
|
57
229
|
|
|
58
|
-
for(const
|
|
230
|
+
for(const endpoint in main.default){
|
|
59
231
|
/* Generate consumer */
|
|
60
|
-
channel.assertQueue(`req/${pseudoEnv.process.env.SVC_NAME}/${moduleSpace}/${
|
|
232
|
+
channel.assertQueue(`req/${pseudoEnv.process.env.SVC_NAME}/${moduleSpace}/${endpoint}`, {
|
|
61
233
|
durable: true
|
|
62
234
|
})
|
|
63
|
-
channel.consume(`req/${pseudoEnv.process.env.SVC_NAME}/${moduleSpace}/${
|
|
235
|
+
channel.consume(`req/${pseudoEnv.process.env.SVC_NAME}/${moduleSpace}/${endpoint}`, async (message)=>{
|
|
64
236
|
const mqHeader = message.properties.headers
|
|
65
237
|
const mqReq = await this.decryptMessage({
|
|
238
|
+
mode: mqHeader.mode,
|
|
66
239
|
message: message.content.toString(),
|
|
67
240
|
...(mqHeader.auth && { token: mqHeader.auth.token }),
|
|
68
241
|
...(mqHeader.auth && { userAgent: mqHeader.auth.userAgent })
|
|
69
242
|
})
|
|
243
|
+
const trueVersion = mqHeader.version ?
|
|
244
|
+
version.trueVersion({
|
|
245
|
+
endpoint: `/${pseudoEnv.process.env.SVC_NAME}/${moduleSpace}/${endpoint}`,
|
|
246
|
+
version: mqHeader.version
|
|
247
|
+
})
|
|
248
|
+
:
|
|
249
|
+
version.latestVersion()
|
|
250
|
+
|
|
70
251
|
const prep = {
|
|
71
252
|
message: null
|
|
72
253
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if(!
|
|
254
|
+
|
|
255
|
+
try{
|
|
256
|
+
/* Active Endpoint Filter */
|
|
257
|
+
if(!main.default[endpoint].active){
|
|
77
258
|
const response = new ResponseCode()
|
|
78
|
-
response.pushCode("
|
|
79
|
-
this.encryptMessage({
|
|
80
|
-
|
|
259
|
+
response.pushCode("INVALID_ENDPOINT")
|
|
260
|
+
prep["message"] = await this.encryptMessage({
|
|
261
|
+
mode: mqHeader.mode,
|
|
262
|
+
message: response.result
|
|
81
263
|
})
|
|
82
|
-
|
|
264
|
+
throw "invalid_endpoint"
|
|
83
265
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
266
|
+
/* API enforce Auth */
|
|
267
|
+
if(main.default[endpoint].authentication){
|
|
268
|
+
if(!mqHeader.auth && mqHeader.mode != "auth"){
|
|
269
|
+
const response = new ResponseCode()
|
|
270
|
+
response.pushCode("NOT_AUTHENTICATED")
|
|
271
|
+
prep["message"] = await this.encryptMessage({
|
|
272
|
+
mode: mqHeader.mode,
|
|
273
|
+
message: response.result
|
|
274
|
+
})
|
|
275
|
+
throw "not_authenticated"
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* With Auth */
|
|
280
|
+
if(mqHeader.auth && mqHeader.mode == "auth"){
|
|
281
|
+
const { token, userAgent } = mqHeader.auth
|
|
282
|
+
const auth = await this.verifyToken({
|
|
94
283
|
token: token,
|
|
95
284
|
userAgent: userAgent
|
|
96
285
|
})
|
|
286
|
+
|
|
287
|
+
if(auth.checkError()){ // NOT_AUTHENTICATED || SESSION_EXPIRED
|
|
288
|
+
prep["message"] = await this.encryptMessage({
|
|
289
|
+
mode: mqHeader.mode,
|
|
290
|
+
message: auth.result
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
else{ // AUTHENTICATED || REFRESH_SESSION
|
|
294
|
+
const result = await main.default[endpoint].function[`v${trueVersion}`](mqHeader.auth, mqReq.payload)
|
|
295
|
+
const response = new ResponseCode(result)
|
|
296
|
+
if(auth.hasCode("REFRESH_SESSION")) response.pushRefresh(auth.result.data)
|
|
297
|
+
prep["message"] = await this.encryptMessage({
|
|
298
|
+
mode: mqHeader.mode,
|
|
299
|
+
message: response.result,
|
|
300
|
+
token: token,
|
|
301
|
+
userAgent: userAgent
|
|
302
|
+
})
|
|
303
|
+
}
|
|
97
304
|
}
|
|
98
|
-
|
|
99
|
-
|
|
305
|
+
/* Without Auth */
|
|
306
|
+
else{
|
|
307
|
+
const result = await main.default[endpoint].function[`v${trueVersion}`](false, mqReq.payload)
|
|
100
308
|
prep["message"] = await this.encryptMessage({
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
token: token,
|
|
106
|
-
userAgent: userAgent
|
|
309
|
+
mode: mqHeader.mode,
|
|
310
|
+
message: result,
|
|
311
|
+
...(mqHeader.auth && { token: mqHeader.auth.token }),
|
|
312
|
+
...(mqHeader.auth && { userAgent: mqHeader.auth.userAgent })
|
|
107
313
|
})
|
|
108
314
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
channel.ack(message)
|
|
315
|
+
|
|
316
|
+
throw "finish"
|
|
317
|
+
}
|
|
318
|
+
catch(something){
|
|
319
|
+
if(mqReq.trip == "returning"){
|
|
320
|
+
channel.sendToQueue(message.properties.replyTo, Buffer.from(prep.message), {
|
|
321
|
+
correlationId: message.properties.correlationId,
|
|
322
|
+
headers:{
|
|
323
|
+
mode: mqHeader.mode,
|
|
324
|
+
...(mqHeader.version && { version: mqHeader.version }),
|
|
325
|
+
...(mqHeader.auth && { auth: mqHeader.auth })
|
|
326
|
+
},
|
|
327
|
+
})
|
|
328
|
+
channel.ack(message)
|
|
329
|
+
}
|
|
125
330
|
}
|
|
126
331
|
},{
|
|
127
332
|
noAck: false
|
|
@@ -132,10 +337,11 @@ export default {
|
|
|
132
337
|
// connection.close()
|
|
133
338
|
})
|
|
134
339
|
},
|
|
135
|
-
publish: function({topic, auth=null, trip="passby", data}){
|
|
340
|
+
publish: function({topic, version, mode="auth", auth=null, trip="passby", data}){
|
|
136
341
|
/* Usage */
|
|
137
342
|
// publish({
|
|
138
343
|
// topic: <topic start at svc :String>,
|
|
344
|
+
// mode: <"auth"|"no auth" :String>
|
|
139
345
|
// auth:{
|
|
140
346
|
// token: <auth token :String>,
|
|
141
347
|
// userAgent: <ua string :String>,
|
|
@@ -172,6 +378,7 @@ export default {
|
|
|
172
378
|
}
|
|
173
379
|
/* Main publisher */
|
|
174
380
|
const mqReq = await this.encryptMessage({
|
|
381
|
+
mode: mode,
|
|
175
382
|
message: prep.message,
|
|
176
383
|
...(auth && { token: auth.token }),
|
|
177
384
|
...(auth && { userAgent: auth.userAgent })
|
|
@@ -179,9 +386,13 @@ export default {
|
|
|
179
386
|
|
|
180
387
|
channel.assertQueue(prep.topic, { durable: true })
|
|
181
388
|
channel.sendToQueue(prep.topic, Buffer.from(mqReq), {
|
|
389
|
+
headers:{
|
|
390
|
+
...(version && { version: version }),
|
|
391
|
+
mode: mode,
|
|
392
|
+
...(auth && { auth: auth })
|
|
393
|
+
},
|
|
182
394
|
...(trip == "returning" && { correlationId: prep.message.senderAddress }),
|
|
183
395
|
...(trip == "returning" && { replyTo: `res/${topic}` }),
|
|
184
|
-
...(auth && { headers:{auth: auth} })
|
|
185
396
|
})
|
|
186
397
|
|
|
187
398
|
/* Resolvation According to Trip */
|
|
@@ -189,9 +400,17 @@ export default {
|
|
|
189
400
|
/* Creates consumer for returning messages */
|
|
190
401
|
channel.assertQueue(`res/${topic}`, { durable: true })
|
|
191
402
|
channel.consume(`res/${topic}`, async (message)=>{
|
|
403
|
+
/* Differentiate normal flow with refresh session flow */
|
|
404
|
+
const sessionRefresh = ()=>{
|
|
405
|
+
const response = new ResponseCode(message.content.toString())
|
|
406
|
+
if(response.hasCode("REFRESH_SESSION")) return true
|
|
407
|
+
else return false
|
|
408
|
+
}
|
|
192
409
|
const mqRes = await this.decryptMessage({
|
|
410
|
+
mode: mode,
|
|
193
411
|
message: message.content.toString(),
|
|
194
|
-
...(auth && { token: auth.token }),
|
|
412
|
+
...((auth && !sessionRefresh()) && { token: auth.token }),
|
|
413
|
+
...((auth && sessionRefresh()) && { token: message.content.toString().data.token }),
|
|
195
414
|
...(auth && { userAgent: auth.userAgent })
|
|
196
415
|
})
|
|
197
416
|
|
|
@@ -218,58 +437,134 @@ export default {
|
|
|
218
437
|
})
|
|
219
438
|
})
|
|
220
439
|
},
|
|
221
|
-
encryptMessage: function({message, token=null, userAgent=null}){
|
|
440
|
+
encryptMessage: function({mode="auth", message, token=null, userAgent=null}){
|
|
222
441
|
return new Promise(async (resolve, reject)=>{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
442
|
+
if(mode == "auth"){
|
|
443
|
+
/* Active Auth Session */
|
|
444
|
+
if(token && userAgent){
|
|
445
|
+
const { userId } = this.getUserInfo({ tokenBody: token.split(".")[0] })
|
|
446
|
+
const uaHash = crypto.hash("sha256", switchPourStr(userAgent, pseudoEnv.process.env.TOKEN_UA_SALT))
|
|
447
|
+
await redis.connect().catch(error => {})
|
|
448
|
+
const authKey = await redis.get(`auth:session:long:${userId}:${uaHash}`)
|
|
449
|
+
const hash = crypto.hash("sha256", switchPourStr(authKey, pseudoEnv.process.env.RABBIT_MESSAGE_SALT))
|
|
450
|
+
const key = hash.substring(0, 16)
|
|
451
|
+
const iv = hash.substring(48)
|
|
233
452
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
453
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", Buffer.from(key), Buffer.from(iv))
|
|
454
|
+
let encrypted = cipher.update(JSON.stringify(message), "utf-8", "base64")
|
|
455
|
+
encrypted += cipher.final("base64")
|
|
456
|
+
return resolve(encrypted)
|
|
457
|
+
}
|
|
458
|
+
/* No Auth */
|
|
459
|
+
else{
|
|
460
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_KEY), Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_IV))
|
|
461
|
+
let encrypted = cipher.update(JSON.stringify(message), "utf-8", "base64")
|
|
462
|
+
encrypted += cipher.final("base64")
|
|
463
|
+
return resolve(encrypted)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
else if(mode == "no auth"){
|
|
467
|
+
/* Unchecked Token (Illegal/Refresh) */
|
|
468
|
+
if(token){
|
|
469
|
+
const {key, iv} = pipe(token)
|
|
470
|
+
.then(token=> token.split(".")[0])
|
|
471
|
+
.then(tokenBody=> this.getUserInfo({tokenBody: tokenBody}))
|
|
472
|
+
.then(({userName, userId, displayName})=>{
|
|
473
|
+
return switchPourStr(
|
|
474
|
+
userName,
|
|
475
|
+
pseudoEnv.process.env.RABBIT_MESSAGE_KEY,
|
|
476
|
+
userId,
|
|
477
|
+
pseudoEnv.process.env.RABBIT_MESSAGE_IV,
|
|
478
|
+
displayName,
|
|
479
|
+
)
|
|
480
|
+
})
|
|
481
|
+
.then(mixWord=> crypto.hash("sha256", mixWord))
|
|
482
|
+
.then(hash=>{
|
|
483
|
+
return {
|
|
484
|
+
key: hash.substring(0, 16),
|
|
485
|
+
iv: hash.substring(48)
|
|
486
|
+
}
|
|
487
|
+
})
|
|
488
|
+
.result
|
|
489
|
+
|
|
490
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", Buffer.from(key), Buffer.from(iv))
|
|
491
|
+
let encrypted = cipher.update(JSON.stringify(message), "utf-8", "base64")
|
|
492
|
+
encrypted += cipher.final("base64")
|
|
493
|
+
return resolve(encrypted)
|
|
494
|
+
}
|
|
495
|
+
/* No Auth */
|
|
496
|
+
else{
|
|
497
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_KEY), Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_IV))
|
|
498
|
+
let encrypted = cipher.update(JSON.stringify(message), "utf-8", "base64")
|
|
499
|
+
encrypted += cipher.final("base64")
|
|
500
|
+
return resolve(encrypted)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
246
503
|
})
|
|
247
504
|
},
|
|
248
|
-
decryptMessage: function({message, token=null, userAgent=null}){
|
|
505
|
+
decryptMessage: function({mode="auth", message, token=null, userAgent=null}){
|
|
249
506
|
return new Promise(async (resolve, reject)=>{
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
507
|
+
if(mode == "auth"){
|
|
508
|
+
/* Active Auth Session */
|
|
509
|
+
if(token && userAgent){
|
|
510
|
+
const { userId } = this.getUserInfo({ tokenBody: token.split(".")[0] })
|
|
511
|
+
const uaHash = crypto.hash("sha256", switchPourStr(userAgent, pseudoEnv.process.env.TOKEN_UA_SALT))
|
|
512
|
+
await redis.connect().catch(error => {})
|
|
513
|
+
const authKey = await redis.get(`auth:session:long:${userId}:${uaHash}`)
|
|
514
|
+
const hash = crypto.hash("sha256", switchPourStr(authKey, pseudoEnv.process.env.RABBIT_MESSAGE_SALT))
|
|
515
|
+
const key = hash.substring(0, 16)
|
|
516
|
+
const iv = hash.substring(48)
|
|
260
517
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
518
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", Buffer.from(key), Buffer.from(iv))
|
|
519
|
+
let decrypted = decipher.update(message, "base64", "utf-8")
|
|
520
|
+
decrypted += decipher.final("utf-8")
|
|
521
|
+
return resolve(JSON.parse(decrypted))
|
|
522
|
+
}
|
|
523
|
+
/* No Auth */
|
|
524
|
+
else{
|
|
525
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_KEY), Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_IV))
|
|
526
|
+
let decrypted = decipher.update(message, "base64", "utf-8")
|
|
527
|
+
decrypted += decipher.final("utf-8")
|
|
528
|
+
return resolve(JSON.parse(decrypted))
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
else if(mode == "no auth"){
|
|
532
|
+
/* Unchecked Token (Illegal/Refresh) */
|
|
533
|
+
if(token){
|
|
534
|
+
const {key, iv} = pipe(token)
|
|
535
|
+
.then(token=> token.split(".")[0])
|
|
536
|
+
.then(tokenBody=> this.getUserInfo({tokenBody: tokenBody}))
|
|
537
|
+
.then(({userName, userId, displayName})=>{
|
|
538
|
+
return switchPourStr(
|
|
539
|
+
userName,
|
|
540
|
+
pseudoEnv.process.env.RABBIT_MESSAGE_KEY,
|
|
541
|
+
userId,
|
|
542
|
+
pseudoEnv.process.env.RABBIT_MESSAGE_IV,
|
|
543
|
+
displayName,
|
|
544
|
+
)
|
|
545
|
+
})
|
|
546
|
+
.then(mixWord=> crypto.hash("sha256", mixWord))
|
|
547
|
+
.then(hash=>{
|
|
548
|
+
return {
|
|
549
|
+
key: hash.substring(0, 16),
|
|
550
|
+
iv: hash.substring(48)
|
|
551
|
+
}
|
|
552
|
+
})
|
|
553
|
+
.result
|
|
554
|
+
|
|
555
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", Buffer.from(key), Buffer.from(iv))
|
|
556
|
+
let decrypted = decipher.update(message, "base64", "utf-8")
|
|
557
|
+
decrypted += decipher.final("utf-8")
|
|
558
|
+
return resolve(JSON.parse(decrypted))
|
|
559
|
+
}
|
|
560
|
+
/* No Auth */
|
|
561
|
+
else{
|
|
562
|
+
const decipher = crypto.createDecipheriv("aes-128-cbc", Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_KEY), Buffer.from(pseudoEnv.process.env.RABBIT_MESSAGE_IV))
|
|
563
|
+
let decrypted = decipher.update(message, "base64", "utf-8")
|
|
564
|
+
decrypted += decipher.final("utf-8")
|
|
565
|
+
return resolve(JSON.parse(decrypted))
|
|
566
|
+
}
|
|
567
|
+
}
|
|
273
568
|
})
|
|
274
569
|
},
|
|
275
570
|
verifyToken: function({token, userAgent}){
|
|
@@ -277,12 +572,9 @@ export default {
|
|
|
277
572
|
return new Promise(async (resolve, reject)=>{
|
|
278
573
|
try{
|
|
279
574
|
await this.publish({
|
|
280
|
-
topic: "
|
|
575
|
+
topic: "authenthor/session/svVerifyToken",
|
|
576
|
+
mode: "no auth",
|
|
281
577
|
trip: "returning",
|
|
282
|
-
auth:{
|
|
283
|
-
token: token,
|
|
284
|
-
userAgent: userAgent,
|
|
285
|
-
},
|
|
286
578
|
data:{
|
|
287
579
|
token: token,
|
|
288
580
|
userAgent: userAgent
|
|
@@ -315,4 +607,13 @@ export default {
|
|
|
315
607
|
.then(circular=> circular.user)
|
|
316
608
|
.result // { userId, userName, displayName }
|
|
317
609
|
},
|
|
610
|
+
update: function(){
|
|
611
|
+
version.update()
|
|
612
|
+
},
|
|
613
|
+
apiVer: function(){
|
|
614
|
+
return version.deprecatedVersion()+1
|
|
615
|
+
},
|
|
616
|
+
latestVer: function(){
|
|
617
|
+
return version.latestVersion()
|
|
618
|
+
}
|
|
318
619
|
}
|