godprotocol 2.3.15 → 2.3.17
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,17 @@ 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_name = ver.config?.db_name === true ? version : ver.config?.db_name;
|
|
31
|
+
|
|
32
|
+
this.db_prefix =
|
|
33
|
+
ver.config?.db_prefix === true ? version : ver.config?.db_prefix;
|
|
34
|
+
|
|
30
35
|
return ver;
|
|
31
36
|
};
|
|
32
37
|
|
|
@@ -74,10 +79,12 @@ class Route_table extends Headers {
|
|
|
74
79
|
return route;
|
|
75
80
|
};
|
|
76
81
|
|
|
82
|
+
getValue = (obj, path) => path.split(".").reduce((o, key) => o?.[key], obj);
|
|
83
|
+
|
|
77
84
|
check_validation = async (rule, data) => {
|
|
78
|
-
let { prop, type, required } = rule;
|
|
85
|
+
let { prop, type, required, enum: allowed } = rule;
|
|
79
86
|
|
|
80
|
-
let data_value = data
|
|
87
|
+
let data_value = this.getValue(data, prop);
|
|
81
88
|
|
|
82
89
|
if (data_value === undefined && rule.hasOwnProperty("default_value")) {
|
|
83
90
|
data_value = rule.default_value;
|
|
@@ -90,92 +97,139 @@ class Route_table extends Headers {
|
|
|
90
97
|
ok: false,
|
|
91
98
|
message: `Field '${prop}' is required`,
|
|
92
99
|
};
|
|
93
|
-
} else {
|
|
94
|
-
return { ok: true };
|
|
95
100
|
}
|
|
101
|
+
return { ok: true };
|
|
96
102
|
}
|
|
97
103
|
|
|
104
|
+
// type validation
|
|
105
|
+
// =========================
|
|
106
|
+
// Type validation
|
|
107
|
+
// =========================
|
|
108
|
+
|
|
98
109
|
if (type) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
let descriptor = type;
|
|
111
|
+
|
|
112
|
+
// Logical schemas may provide a map:
|
|
113
|
+
// type: {
|
|
114
|
+
// intervals: { value: "array", min: 1 },
|
|
115
|
+
// throttle: { value: "number", min: 1000 }
|
|
116
|
+
// }
|
|
117
|
+
if (typeof type === "object" && !Array.isArray(type)) {
|
|
118
|
+
descriptor = type[prop];
|
|
119
|
+
|
|
120
|
+
// No type rule for this property
|
|
121
|
+
if (!descriptor) {
|
|
122
|
+
descriptor = null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (descriptor) {
|
|
127
|
+
// Allow shorthand:
|
|
128
|
+
// "string"
|
|
129
|
+
// or
|
|
130
|
+
// { value: "string", ... }
|
|
131
|
+
if (typeof descriptor === "string") {
|
|
132
|
+
descriptor = {
|
|
133
|
+
value: descriptor,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const expected = descriptor.value;
|
|
138
|
+
|
|
139
|
+
let actual;
|
|
140
|
+
|
|
141
|
+
if (expected === "array") {
|
|
142
|
+
actual = Array.isArray(data_value) ? "array" : typeof data_value;
|
|
143
|
+
} else {
|
|
144
|
+
actual = typeof data_value;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (actual !== expected) {
|
|
107
148
|
return {
|
|
108
149
|
ok: false,
|
|
109
|
-
message: `Field '${prop}' must be of type '${
|
|
150
|
+
message: `Field '${prop}' must be of type '${expected}', got '${actual}'`,
|
|
110
151
|
};
|
|
152
|
+
}
|
|
111
153
|
}
|
|
112
154
|
}
|
|
113
155
|
|
|
156
|
+
// enum validation
|
|
157
|
+
if (
|
|
158
|
+
data_value !== undefined &&
|
|
159
|
+
data_value !== null &&
|
|
160
|
+
allowed &&
|
|
161
|
+
!allowed.includes(data_value)
|
|
162
|
+
) {
|
|
163
|
+
return {
|
|
164
|
+
ok: false,
|
|
165
|
+
message: `Field '${prop}' must be one of: ${allowed.join(", ")}`,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
114
169
|
return { ok: true };
|
|
115
170
|
};
|
|
116
171
|
|
|
117
172
|
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
|
-
);
|
|
173
|
+
for (const section of Object.keys(schema)) {
|
|
174
|
+
const rules = schema[section];
|
|
175
|
+
const target = data[section] || {};
|
|
176
|
+
|
|
177
|
+
for (const prop in rules) {
|
|
178
|
+
const rule = rules[prop];
|
|
179
|
+
|
|
180
|
+
if (prop === "$logic") {
|
|
181
|
+
// OR logic
|
|
182
|
+
if (rule.or) {
|
|
183
|
+
for (const orRule of rule.or) {
|
|
184
|
+
let passed = false;
|
|
185
|
+
|
|
186
|
+
for (const property of orRule.properties) {
|
|
187
|
+
const result = await this.check_validation(
|
|
188
|
+
{ prop: property, ...orRule },
|
|
189
|
+
target,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
if (result.ok) {
|
|
193
|
+
passed = true;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
160
197
|
|
|
161
|
-
if (
|
|
198
|
+
if (orRule.required && !passed) {
|
|
162
199
|
return {
|
|
163
200
|
ok: false,
|
|
164
|
-
message: `
|
|
201
|
+
message: `At least one of the following fields is required: ${orRule.properties.join(
|
|
202
|
+
", ",
|
|
203
|
+
)}`,
|
|
165
204
|
};
|
|
166
205
|
}
|
|
167
206
|
}
|
|
168
207
|
}
|
|
208
|
+
|
|
209
|
+
// AND logic
|
|
210
|
+
if (rule.and) {
|
|
211
|
+
for (const andRule of rule.and) {
|
|
212
|
+
for (const property of andRule.properties) {
|
|
213
|
+
const result = await this.check_validation(
|
|
214
|
+
{ prop: property, ...andRule },
|
|
215
|
+
target,
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
if (!result.ok) {
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
continue;
|
|
169
226
|
}
|
|
170
|
-
}
|
|
171
227
|
|
|
172
|
-
|
|
173
|
-
{ prop, ...rule },
|
|
174
|
-
data_body,
|
|
175
|
-
);
|
|
228
|
+
const result = await this.check_validation({ prop, ...rule }, target);
|
|
176
229
|
|
|
177
|
-
|
|
178
|
-
|
|
230
|
+
if (!result.ok) {
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
179
233
|
}
|
|
180
234
|
}
|
|
181
235
|
|
|
@@ -34,6 +34,7 @@ class Services {
|
|
|
34
34
|
constructor() {
|
|
35
35
|
this.services = new Object();
|
|
36
36
|
|
|
37
|
+
this.dbs = 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,21 @@ class Services {
|
|
|
156
154
|
};
|
|
157
155
|
|
|
158
156
|
platform_db = async () => {
|
|
159
|
-
|
|
157
|
+
let prefix = this.db_prefix,
|
|
158
|
+
name = this.db_name || this.db_config.name;
|
|
159
|
+
|
|
160
|
+
if (prefix) {
|
|
161
|
+
name = `${prefix}:${name}`;
|
|
162
|
+
}
|
|
160
163
|
|
|
161
|
-
|
|
164
|
+
let db = this.dbs[name];
|
|
165
|
+
if (!db) {
|
|
166
|
+
db = new DB({ ...this.db_config, name }, this);
|
|
167
|
+
|
|
168
|
+
this.dbs[name] = db;
|
|
169
|
+
}
|
|
162
170
|
|
|
163
|
-
return
|
|
171
|
+
return db;
|
|
164
172
|
};
|
|
165
173
|
|
|
166
174
|
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;
|