godprotocol 2.3.15 → 2.3.16
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
|
@@ -284,7 +284,7 @@ class Headers extends Services {
|
|
|
284
284
|
|
|
285
285
|
let val;
|
|
286
286
|
if (config.security?.includes("auth_token")) {
|
|
287
|
-
if (authorisation?.startsWith("p")) {
|
|
287
|
+
if (authorisation?.startsWith("p") || authorisation?.startsWith("o")) {
|
|
288
288
|
val = await this.validate_api_key(authorisation);
|
|
289
289
|
} else
|
|
290
290
|
val = await this.validate_third_party(
|
|
@@ -21,12 +21,15 @@ class Route_table extends Headers {
|
|
|
21
21
|
this.validators = {};
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
get_version = (version) => {
|
|
24
|
+
get_version = (version = this.active_version) => {
|
|
25
25
|
let ver = this.versions[version];
|
|
26
26
|
if (!ver) return;
|
|
27
27
|
|
|
28
28
|
this.active_version = version;
|
|
29
29
|
|
|
30
|
+
this.db_prefix =
|
|
31
|
+
ver.config?.db_prefix === true ? version : ver.config?.db_prefix;
|
|
32
|
+
|
|
30
33
|
return ver;
|
|
31
34
|
};
|
|
32
35
|
|
|
@@ -74,10 +77,12 @@ class Route_table extends Headers {
|
|
|
74
77
|
return route;
|
|
75
78
|
};
|
|
76
79
|
|
|
80
|
+
getValue = (obj, path) => path.split(".").reduce((o, key) => o?.[key], obj);
|
|
81
|
+
|
|
77
82
|
check_validation = async (rule, data) => {
|
|
78
|
-
let { prop, type, required } = rule;
|
|
83
|
+
let { prop, type, required, enum: allowed } = rule;
|
|
79
84
|
|
|
80
|
-
let data_value = data
|
|
85
|
+
let data_value = this.getValue(data, prop);
|
|
81
86
|
|
|
82
87
|
if (data_value === undefined && rule.hasOwnProperty("default_value")) {
|
|
83
88
|
data_value = rule.default_value;
|
|
@@ -90,92 +95,139 @@ class Route_table extends Headers {
|
|
|
90
95
|
ok: false,
|
|
91
96
|
message: `Field '${prop}' is required`,
|
|
92
97
|
};
|
|
93
|
-
} else {
|
|
94
|
-
return { ok: true };
|
|
95
98
|
}
|
|
99
|
+
return { ok: true };
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
// type validation
|
|
103
|
+
// =========================
|
|
104
|
+
// Type validation
|
|
105
|
+
// =========================
|
|
106
|
+
|
|
98
107
|
if (type) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
let descriptor = type;
|
|
109
|
+
|
|
110
|
+
// Logical schemas may provide a map:
|
|
111
|
+
// type: {
|
|
112
|
+
// intervals: { value: "array", min: 1 },
|
|
113
|
+
// throttle: { value: "number", min: 1000 }
|
|
114
|
+
// }
|
|
115
|
+
if (typeof type === "object" && !Array.isArray(type)) {
|
|
116
|
+
descriptor = type[prop];
|
|
117
|
+
|
|
118
|
+
// No type rule for this property
|
|
119
|
+
if (!descriptor) {
|
|
120
|
+
descriptor = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (descriptor) {
|
|
125
|
+
// Allow shorthand:
|
|
126
|
+
// "string"
|
|
127
|
+
// or
|
|
128
|
+
// { value: "string", ... }
|
|
129
|
+
if (typeof descriptor === "string") {
|
|
130
|
+
descriptor = {
|
|
131
|
+
value: descriptor,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const expected = descriptor.value;
|
|
136
|
+
|
|
137
|
+
let actual;
|
|
138
|
+
|
|
139
|
+
if (expected === "array") {
|
|
140
|
+
actual = Array.isArray(data_value) ? "array" : typeof data_value;
|
|
141
|
+
} else {
|
|
142
|
+
actual = typeof data_value;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (actual !== expected) {
|
|
107
146
|
return {
|
|
108
147
|
ok: false,
|
|
109
|
-
message: `Field '${prop}' must be of type '${
|
|
148
|
+
message: `Field '${prop}' must be of type '${expected}', got '${actual}'`,
|
|
110
149
|
};
|
|
150
|
+
}
|
|
111
151
|
}
|
|
112
152
|
}
|
|
113
153
|
|
|
154
|
+
// enum validation
|
|
155
|
+
if (
|
|
156
|
+
data_value !== undefined &&
|
|
157
|
+
data_value !== null &&
|
|
158
|
+
allowed &&
|
|
159
|
+
!allowed.includes(data_value)
|
|
160
|
+
) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
message: `Field '${prop}' must be one of: ${allowed.join(", ")}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
114
167
|
return { ok: true };
|
|
115
168
|
};
|
|
116
169
|
|
|
117
170
|
validate = async (schema, data) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
message: `At least one of the following fields is required: ${or_rule.properties.join(
|
|
143
|
-
", ",
|
|
144
|
-
)}`,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
let and_logic = rule.and;
|
|
151
|
-
if (and_logic) {
|
|
152
|
-
for (let a = 0; a < and_logic.length; a++) {
|
|
153
|
-
let and_rule = and_logic[a];
|
|
154
|
-
|
|
155
|
-
for (let prop of and_rule.properties) {
|
|
156
|
-
let and_rule_check = await this.check_validation(
|
|
157
|
-
{ prop, ...and_rule },
|
|
158
|
-
data_body,
|
|
159
|
-
);
|
|
171
|
+
for (const section of Object.keys(schema)) {
|
|
172
|
+
const rules = schema[section];
|
|
173
|
+
const target = data[section] || {};
|
|
174
|
+
|
|
175
|
+
for (const prop in rules) {
|
|
176
|
+
const rule = rules[prop];
|
|
177
|
+
|
|
178
|
+
if (prop === "$logic") {
|
|
179
|
+
// OR logic
|
|
180
|
+
if (rule.or) {
|
|
181
|
+
for (const orRule of rule.or) {
|
|
182
|
+
let passed = false;
|
|
183
|
+
|
|
184
|
+
for (const property of orRule.properties) {
|
|
185
|
+
const result = await this.check_validation(
|
|
186
|
+
{ prop: property, ...orRule },
|
|
187
|
+
target,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
if (result.ok) {
|
|
191
|
+
passed = true;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
160
195
|
|
|
161
|
-
if (
|
|
196
|
+
if (orRule.required && !passed) {
|
|
162
197
|
return {
|
|
163
198
|
ok: false,
|
|
164
|
-
message: `
|
|
199
|
+
message: `At least one of the following fields is required: ${orRule.properties.join(
|
|
200
|
+
", ",
|
|
201
|
+
)}`,
|
|
165
202
|
};
|
|
166
203
|
}
|
|
167
204
|
}
|
|
168
205
|
}
|
|
206
|
+
|
|
207
|
+
// AND logic
|
|
208
|
+
if (rule.and) {
|
|
209
|
+
for (const andRule of rule.and) {
|
|
210
|
+
for (const property of andRule.properties) {
|
|
211
|
+
const result = await this.check_validation(
|
|
212
|
+
{ prop: property, ...andRule },
|
|
213
|
+
target,
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
if (!result.ok) {
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
continue;
|
|
169
224
|
}
|
|
170
|
-
}
|
|
171
225
|
|
|
172
|
-
|
|
173
|
-
{ prop, ...rule },
|
|
174
|
-
data_body,
|
|
175
|
-
);
|
|
226
|
+
const result = await this.check_validation({ prop, ...rule }, target);
|
|
176
227
|
|
|
177
|
-
|
|
178
|
-
|
|
228
|
+
if (!result.ok) {
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
179
231
|
}
|
|
180
232
|
}
|
|
181
233
|
|
|
@@ -34,6 +34,7 @@ class Services {
|
|
|
34
34
|
constructor() {
|
|
35
35
|
this.services = new Object();
|
|
36
36
|
|
|
37
|
+
this.db_prefixes = new Object();
|
|
37
38
|
this.load_services(gp_services);
|
|
38
39
|
}
|
|
39
40
|
|
|
@@ -46,18 +47,14 @@ class Services {
|
|
|
46
47
|
get_token = async (service, id) => {
|
|
47
48
|
let token;
|
|
48
49
|
|
|
49
|
-
// debug(service, id, "gettok");
|
|
50
50
|
let db = await this.platform_db();
|
|
51
51
|
token = await db.read_cache(
|
|
52
52
|
{ platform_uri: service.uri, id: id.profile },
|
|
53
53
|
"token",
|
|
54
54
|
);
|
|
55
55
|
|
|
56
|
-
// debug(token, "in-cache");
|
|
57
56
|
if (token) return token.token;
|
|
58
57
|
try {
|
|
59
|
-
// debug(this.api_key, gp_services.profile);
|
|
60
|
-
|
|
61
58
|
let gp_profile = gp_services().profile;
|
|
62
59
|
let ftch = await fetch(`${gp_profile.url}/get_token`, {
|
|
63
60
|
method: "POST",
|
|
@@ -70,9 +67,7 @@ class Services {
|
|
|
70
67
|
body: JSON.stringify({ platform_uri: service.uri, ...id }),
|
|
71
68
|
});
|
|
72
69
|
|
|
73
|
-
// debug("whats it like??");
|
|
74
70
|
token = await ftch.json();
|
|
75
|
-
// debug(token, "HOOWWW");
|
|
76
71
|
|
|
77
72
|
if (token?.ok) {
|
|
78
73
|
await db.save_cache(
|
|
@@ -100,6 +95,7 @@ class Services {
|
|
|
100
95
|
if (!servic) return;
|
|
101
96
|
|
|
102
97
|
return {
|
|
98
|
+
uri: servic.uri,
|
|
103
99
|
call: async (path, body, header) => {
|
|
104
100
|
let headers = {
|
|
105
101
|
"Content-Type": "application/json",
|
|
@@ -107,7 +103,9 @@ class Services {
|
|
|
107
103
|
"x-api-version": servic.api_version || "v1",
|
|
108
104
|
};
|
|
109
105
|
let token;
|
|
110
|
-
if (
|
|
106
|
+
if (servic.profile_key) {
|
|
107
|
+
headers["Authorization"] = `${servic.profile_key}`;
|
|
108
|
+
} else if (header?.token || header?.profile) {
|
|
111
109
|
if (header.token) {
|
|
112
110
|
token = header.token;
|
|
113
111
|
} else if (header.profile) {
|
|
@@ -156,11 +154,26 @@ class Services {
|
|
|
156
154
|
};
|
|
157
155
|
|
|
158
156
|
platform_db = async () => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
let prefix = this.db_prefix;
|
|
158
|
+
let db;
|
|
159
|
+
if (prefix) {
|
|
160
|
+
db = this.db_prefixes[prefix];
|
|
161
|
+
if (!db) {
|
|
162
|
+
let conf = { ...this.db_config };
|
|
163
|
+
conf.name = `${prefix}:${this.db_config.name}`;
|
|
164
|
+
|
|
165
|
+
db = new DB(conf, this);
|
|
166
|
+
this.db_prefixes[prefix] = db;
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
db = this.db;
|
|
170
|
+
if (!db) {
|
|
171
|
+
db = new DB(this.db_config, this);
|
|
172
|
+
this.db = db;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
162
175
|
|
|
163
|
-
return
|
|
176
|
+
return db;
|
|
164
177
|
};
|
|
165
178
|
|
|
166
179
|
handle_webhook_prior = async (req) => {
|
|
@@ -35,6 +35,7 @@ const applyCors = (req, res) => {
|
|
|
35
35
|
res.setHeader(
|
|
36
36
|
"Access-Control-Allow-Headers",
|
|
37
37
|
"Content-Type, Authorization, x-api-version, x-api-key, x-platform",
|
|
38
|
+
"x-secret",
|
|
38
39
|
);
|
|
39
40
|
|
|
40
41
|
// IMPORTANT: do NOT enable credentials with "*"
|
|
@@ -75,6 +76,10 @@ const respond = (result, res) => {
|
|
|
75
76
|
response.token = result.token;
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
if (result?.next) {
|
|
80
|
+
response.next = result.next;
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
const status = result?.status || (result?.ok ? 200 : 403);
|
|
79
84
|
|
|
80
85
|
res.statusCode = status;
|