skapi-js 0.0.4 → 0.0.42
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/README.md +1 -1
- package/deploy.py +8 -0
- package/dist/skapi.js +1 -1
- package/dist/skapi.js.map +1 -1
- package/dist/skapi.module.js +3 -0
- package/dist/skapi.module.js.LICENSE.txt +21 -0
- package/dist/skapi.module.js.map +1 -0
- package/package.json +5 -4
- package/src/decorators.ts +2 -1
- package/src/skapi.ts +85 -125
- package/src/utils.ts +31 -27
- package/tsconfig.json +2 -2
- package/webpack.config.js +16 -12
- package/index.html +0 -90
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skapi-js",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "skapi javascript library",
|
|
5
|
-
"main": "./dist/skapi.js",
|
|
3
|
+
"version": "0.0.42",
|
|
4
|
+
"description": "skapi serverless cloud javascript library",
|
|
5
|
+
"main": "./dist/skapi.module.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "npx tsc ; npx webpack --config webpack.config.js ; npx typedoc"
|
|
8
8
|
},
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"backend",
|
|
28
28
|
"serverless",
|
|
29
29
|
"skapi",
|
|
30
|
-
"api"
|
|
30
|
+
"api",
|
|
31
|
+
"cloud"
|
|
31
32
|
],
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"amazon-cognito-identity-js": "^5.2.12"
|
package/src/decorators.ts
CHANGED
|
@@ -29,7 +29,8 @@ function formResponse() {
|
|
|
29
29
|
|
|
30
30
|
// form element action
|
|
31
31
|
let href = new URL(form.action);
|
|
32
|
-
let response_key = sha256(form.action);
|
|
32
|
+
// let response_key = sha256(form.action);
|
|
33
|
+
let response_key = form.action;
|
|
33
34
|
let timestamp = Date.now().toString();
|
|
34
35
|
|
|
35
36
|
window.sessionStorage.setItem(response_key, JSON.stringify({ [timestamp]: response }));
|
package/src/skapi.ts
CHANGED
|
@@ -110,7 +110,21 @@ export default class Skapi {
|
|
|
110
110
|
// public
|
|
111
111
|
|
|
112
112
|
/** Current logged in user object. null if not logged. */
|
|
113
|
-
|
|
113
|
+
__user: User | null = null;
|
|
114
|
+
|
|
115
|
+
get user() {
|
|
116
|
+
if (this.__user && Object.keys(this.__user).length) {
|
|
117
|
+
return JSON.parse(JSON.stringify(this.__user));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
set user(value) {
|
|
125
|
+
// setting user is bypassed
|
|
126
|
+
}
|
|
127
|
+
|
|
114
128
|
/** Connected service object. null if connection failed. */
|
|
115
129
|
connection: Connection | null = null;
|
|
116
130
|
host: string = 'skapi';
|
|
@@ -411,7 +425,7 @@ export default class Skapi {
|
|
|
411
425
|
user.access_group = Number(this.session.idToken.payload.access_group);
|
|
412
426
|
user.user_id = user.sub;
|
|
413
427
|
delete user.sub;
|
|
414
|
-
this.
|
|
428
|
+
this.__user = user;
|
|
415
429
|
res(user);
|
|
416
430
|
}
|
|
417
431
|
});
|
|
@@ -577,6 +591,10 @@ export default class Skapi {
|
|
|
577
591
|
return await this.request(p.url, option || null, { method: 'get', auth: p.url.includes('/auth/'), contentType: null, responseType: 'blob' });
|
|
578
592
|
}
|
|
579
593
|
|
|
594
|
+
async mock(data, options) {
|
|
595
|
+
return this.request('test-api', data, options);
|
|
596
|
+
}
|
|
597
|
+
|
|
580
598
|
/**
|
|
581
599
|
* Sends post request to your custom server using Skapi's secure API layer.</br>
|
|
582
600
|
* You must set your secret API key from the Skapi's admin page.</br>
|
|
@@ -735,7 +753,7 @@ export default class Skapi {
|
|
|
735
753
|
* Retrives respond data from form request.
|
|
736
754
|
*
|
|
737
755
|
* ```
|
|
738
|
-
* let respond = skapi.
|
|
756
|
+
* let respond = skapi.getFormResponse();
|
|
739
757
|
* ```
|
|
740
758
|
* @category Connection
|
|
741
759
|
*/
|
|
@@ -835,6 +853,7 @@ export default class Skapi {
|
|
|
835
853
|
case 'signup':
|
|
836
854
|
case 'confirm-signup':
|
|
837
855
|
case 'recover-account':
|
|
856
|
+
case 'test-api':
|
|
838
857
|
case 'service':
|
|
839
858
|
return {
|
|
840
859
|
public: admin.admin_public,
|
|
@@ -1012,7 +1031,7 @@ export default class Skapi {
|
|
|
1012
1031
|
url: isExternalUrl || url,
|
|
1013
1032
|
refresh: isForm ? true : refresh // should not use startKey when post is a form
|
|
1014
1033
|
}); // returns requrestKey | cached data
|
|
1015
|
-
|
|
1034
|
+
|
|
1016
1035
|
if (requestKey && typeof requestKey === 'object') {
|
|
1017
1036
|
return requestKey;
|
|
1018
1037
|
}
|
|
@@ -1093,7 +1112,7 @@ export default class Skapi {
|
|
|
1093
1112
|
}): string | FetchResponse {
|
|
1094
1113
|
|
|
1095
1114
|
let { params = {}, url, refresh = false } = option || {};
|
|
1096
|
-
|
|
1115
|
+
|
|
1097
1116
|
if (params.hasOwnProperty('startKey')) {
|
|
1098
1117
|
if (
|
|
1099
1118
|
typeof params.startKey !== 'object' && !Object.keys(params.startKey).length ||
|
|
@@ -1119,11 +1138,9 @@ export default class Skapi {
|
|
|
1119
1138
|
}
|
|
1120
1139
|
|
|
1121
1140
|
// let hashedParams = createHash('sha256').update(toHash).digest('hex');
|
|
1122
|
-
let hashedParams =
|
|
1141
|
+
let hashedParams = (() => {
|
|
1123
1142
|
if (params && typeof params === 'object' && Object.keys(params).length) {
|
|
1124
1143
|
// hash request parameters
|
|
1125
|
-
let paramsHash = JSON.parse(JSON.stringify(params));
|
|
1126
|
-
|
|
1127
1144
|
function orderObjectKeys(obj: Record<string, any>) {
|
|
1128
1145
|
function sortObject(obj: Record<string, any>): Record<string, any> {
|
|
1129
1146
|
if (typeof obj === 'object' && obj) {
|
|
@@ -1142,11 +1159,12 @@ export default class Skapi {
|
|
|
1142
1159
|
return _obj;
|
|
1143
1160
|
}
|
|
1144
1161
|
|
|
1145
|
-
return JSON.stringify(orderObjectKeys(
|
|
1162
|
+
return url + '/' + JSON.stringify(orderObjectKeys(params));
|
|
1146
1163
|
}
|
|
1147
1164
|
|
|
1148
|
-
return url + this.service;
|
|
1149
|
-
|
|
1165
|
+
return url + '/' + this.service;
|
|
1166
|
+
|
|
1167
|
+
})();
|
|
1150
1168
|
|
|
1151
1169
|
if (refresh && this.__startKey_keys?.[url]?.[hashedParams]) {
|
|
1152
1170
|
// init cache, init startKey
|
|
@@ -1159,7 +1177,8 @@ export default class Skapi {
|
|
|
1159
1177
|
if (Array.isArray(this.__startKey_keys[url][hashedParams]) && this.__startKey_keys[url][hashedParams].length) {
|
|
1160
1178
|
// delete cache of all startkeys
|
|
1161
1179
|
for (let p of this.__startKey_keys[url][hashedParams]) {
|
|
1162
|
-
let hashedParams_cached = hashedParams + sha256(JSON.stringify(p));
|
|
1180
|
+
// let hashedParams_cached = hashedParams + '/' + sha256(JSON.stringify(p));
|
|
1181
|
+
let hashedParams_cached = hashedParams + '/' + JSON.stringify(p);
|
|
1163
1182
|
// let hashedParams_cached = hashedParams + createHash('sha256').update(JSON.stringify(p)).digest('hex');
|
|
1164
1183
|
|
|
1165
1184
|
if (this.__cached_requests?.[url] && this.__cached_requests?.[url]?.[hashedParams_cached]) {
|
|
@@ -1197,7 +1216,8 @@ export default class Skapi {
|
|
|
1197
1216
|
|
|
1198
1217
|
else {
|
|
1199
1218
|
// cache_hashedParams += createHash('sha256').update(last_startKey_key).digest('hex');
|
|
1200
|
-
cache_hashedParams += sha256(last_startKey_key);
|
|
1219
|
+
// cache_hashedParams += sha256(last_startKey_key);
|
|
1220
|
+
cache_hashedParams += ('/' + last_startKey_key);
|
|
1201
1221
|
params.startKey = JSON.parse(last_startKey_key);
|
|
1202
1222
|
}
|
|
1203
1223
|
}
|
|
@@ -1427,13 +1447,9 @@ export default class Skapi {
|
|
|
1427
1447
|
option = checkParams(option || {}, {
|
|
1428
1448
|
record_id: 'string',
|
|
1429
1449
|
access_group: ['number', 'private'],
|
|
1430
|
-
table:
|
|
1431
|
-
if (!option?.record_id) {
|
|
1432
|
-
throw new SkapiError('Either "record_id" or "table" should have a value.', { code: 'INVALID_PARAMETER' });
|
|
1433
|
-
}
|
|
1434
|
-
}],
|
|
1450
|
+
table: 'string',
|
|
1435
1451
|
subscription_group: 'number',
|
|
1436
|
-
reference: 'string',
|
|
1452
|
+
reference: ['string', null],
|
|
1437
1453
|
index: {
|
|
1438
1454
|
name: 'string',
|
|
1439
1455
|
value: ['string', 'number', 'boolean']
|
|
@@ -1459,11 +1475,33 @@ export default class Skapi {
|
|
|
1459
1475
|
throw new SkapiError(`"tags" should be type: <string | string[]>`, { code: 'INVALID_PARAMETER' });
|
|
1460
1476
|
},
|
|
1461
1477
|
config: {
|
|
1462
|
-
reference_limit:
|
|
1478
|
+
reference_limit: (v: number) => {
|
|
1479
|
+
if (v === null) {
|
|
1480
|
+
return null;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
else if (typeof v === 'number') {
|
|
1484
|
+
if (0 > v) {
|
|
1485
|
+
throw new SkapiError(`"reference_limit" should be >= 0`, { code: 'INVALID_PARAMETER' });
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
if (v > 4503599627370546) {
|
|
1489
|
+
throw new SkapiError(`"reference_limit" should be <= 4503599627370546`, { code: 'INVALID_PARAMETER' });
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
return v;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
throw new SkapiError(`"reference_limit" should be type: <number | null>`, { code: 'INVALID_PARAMETER' });
|
|
1496
|
+
},
|
|
1463
1497
|
allow_multiple_reference: 'boolean',
|
|
1464
1498
|
private_access: (v: string | string[]) => {
|
|
1465
1499
|
let param = 'config.private_access';
|
|
1466
1500
|
|
|
1501
|
+
if (v === null) {
|
|
1502
|
+
return null;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1467
1505
|
if (v && typeof v === 'string') {
|
|
1468
1506
|
v = [v];
|
|
1469
1507
|
}
|
|
@@ -1472,7 +1510,7 @@ export default class Skapi {
|
|
|
1472
1510
|
for (let u of v) {
|
|
1473
1511
|
validateUserId(u, `User ID in "${param}"`);
|
|
1474
1512
|
|
|
1475
|
-
if (this.
|
|
1513
|
+
if (this.__user && u === this.__user.user_id) {
|
|
1476
1514
|
throw new SkapiError(`"${param}" should not be the uploader's user ID.`, { code: 'INVALID_PARAMETER' });
|
|
1477
1515
|
}
|
|
1478
1516
|
}
|
|
@@ -1492,6 +1530,10 @@ export default class Skapi {
|
|
|
1492
1530
|
delete option.formData;
|
|
1493
1531
|
delete option.onerror;
|
|
1494
1532
|
|
|
1533
|
+
if (!option?.table && !option?.record_id) {
|
|
1534
|
+
throw new SkapiError('Either "record_id" or "table" should have a value.', { code: 'INVALID_PARAMETER' });
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1495
1537
|
if (option?.index) {
|
|
1496
1538
|
// index name allows periods. white space is invalid.
|
|
1497
1539
|
if (!option.index?.name || typeof option.index?.name !== 'string') {
|
|
@@ -1516,7 +1558,6 @@ export default class Skapi {
|
|
|
1516
1558
|
}
|
|
1517
1559
|
}
|
|
1518
1560
|
|
|
1519
|
-
|
|
1520
1561
|
if (is_admin) {
|
|
1521
1562
|
if (option?.access_group === 'private') {
|
|
1522
1563
|
throw new SkapiError('Service owner cannot write private records.', { code: 'INVALID_REQUEST' });
|
|
@@ -1627,22 +1668,7 @@ export default class Skapi {
|
|
|
1627
1668
|
return v;
|
|
1628
1669
|
}
|
|
1629
1670
|
},
|
|
1630
|
-
tags:
|
|
1631
|
-
if (typeof v === 'string') {
|
|
1632
|
-
return [v];
|
|
1633
|
-
}
|
|
1634
|
-
else if (Array.isArray(v)) {
|
|
1635
|
-
if (v.length > 10) {
|
|
1636
|
-
throw new SkapiError('Cannot query more than 10 tags at once.', { code: 'INVALID_REQUEST' });
|
|
1637
|
-
}
|
|
1638
|
-
for (let s of v) {
|
|
1639
|
-
if (typeof s !== 'string') {
|
|
1640
|
-
throw new SkapiError('Tags should be type: <string | string[]>', { code: 'INVALID_PARAMETER' });
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
return v;
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1671
|
+
tags: 'string'
|
|
1646
1672
|
};
|
|
1647
1673
|
|
|
1648
1674
|
params = checkParams(params || {}, struct, ['table']);
|
|
@@ -1651,73 +1677,11 @@ export default class Skapi {
|
|
|
1651
1677
|
throw new SkapiError('Requires login.', { code: 'INVALID_REQUEST' });
|
|
1652
1678
|
}
|
|
1653
1679
|
|
|
1654
|
-
if (params?.tags) {
|
|
1655
|
-
let tagFetch = [];
|
|
1656
|
-
let getStartKey = fetchOptions?.startKey || null;
|
|
1657
|
-
|
|
1658
|
-
for (let t of params.tags) {
|
|
1659
|
-
let params_copy = JSON.parse(JSON.stringify(params));
|
|
1660
|
-
params_copy.tag = t;
|
|
1661
|
-
delete params_copy.tags;
|
|
1662
|
-
|
|
1663
|
-
let fetchOpt = fetchOptions ? JSON.parse(JSON.stringify(fetchOptions)) : null;
|
|
1664
|
-
if (fetchOpt) {
|
|
1665
|
-
delete fetchOpt.startKey;
|
|
1666
|
-
|
|
1667
|
-
if (getStartKey && getStartKey?.[t]) {
|
|
1668
|
-
fetchOpt.startKey = getStartKey[t];
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
tagFetch.push(this.request(
|
|
1673
|
-
'get-records',
|
|
1674
|
-
params_copy,
|
|
1675
|
-
Object.assign(
|
|
1676
|
-
{ auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.session },
|
|
1677
|
-
{ fetchOptions: fetchOpt }
|
|
1678
|
-
)));
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
let list = [];
|
|
1682
|
-
let startKey = {};
|
|
1683
|
-
let res_all = await Promise.all(tagFetch);
|
|
1684
|
-
|
|
1685
|
-
for (let res of res_all) {
|
|
1686
|
-
for (let i in res.list) {
|
|
1687
|
-
if (tagFetch.includes(res.list[i].rec)) {
|
|
1688
|
-
continue;
|
|
1689
|
-
}
|
|
1690
|
-
tagFetch.push(res.list[i]);
|
|
1691
|
-
list.push(normalize_record_data(res.list[i]));
|
|
1692
|
-
};
|
|
1693
|
-
if (res.startKey) {
|
|
1694
|
-
if (Array.isArray(params.tags)) {
|
|
1695
|
-
let tag = params.tags.splice(0, 1);
|
|
1696
|
-
startKey[tag[0]] = res.startKey;
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
let endOfList = true;
|
|
1702
|
-
for (let k in startKey) {
|
|
1703
|
-
if (startKey[k] && startKey[k] !== 'end') {
|
|
1704
|
-
endOfList = false;
|
|
1705
|
-
break;
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
return {
|
|
1710
|
-
list,
|
|
1711
|
-
endOfList,
|
|
1712
|
-
startKey
|
|
1713
|
-
};
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1716
1680
|
let result = await this.request(
|
|
1717
1681
|
'get-records',
|
|
1718
1682
|
params,
|
|
1719
1683
|
Object.assign(
|
|
1720
|
-
{ auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.
|
|
1684
|
+
{ auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.__user },
|
|
1721
1685
|
{ fetchOptions }
|
|
1722
1686
|
)
|
|
1723
1687
|
);
|
|
@@ -2176,7 +2140,7 @@ export default class Skapi {
|
|
|
2176
2140
|
}
|
|
2177
2141
|
}, ['user_id', 'group']);
|
|
2178
2142
|
|
|
2179
|
-
if (this.
|
|
2143
|
+
if (this.__user && option.user_id === this.__user.user_id) {
|
|
2180
2144
|
throw new SkapiError(`"user_id" cannot be the user's own ID.`, { code: 'INVALID_PARAMETER' });
|
|
2181
2145
|
}
|
|
2182
2146
|
|
|
@@ -2301,7 +2265,7 @@ export default class Skapi {
|
|
|
2301
2265
|
}) || {};
|
|
2302
2266
|
|
|
2303
2267
|
return this.getSubscriptions({
|
|
2304
|
-
subscriber: option.user_id || this.
|
|
2268
|
+
subscriber: option.user_id || this.__user?.user_id,
|
|
2305
2269
|
group: option.group
|
|
2306
2270
|
});
|
|
2307
2271
|
}
|
|
@@ -2319,7 +2283,7 @@ export default class Skapi {
|
|
|
2319
2283
|
}) || {};
|
|
2320
2284
|
|
|
2321
2285
|
let subParams = {
|
|
2322
|
-
subscription: option.user_id || this.
|
|
2286
|
+
subscription: option.user_id || this.__user?.user_id,
|
|
2323
2287
|
group: option.group
|
|
2324
2288
|
};
|
|
2325
2289
|
|
|
@@ -2693,18 +2657,14 @@ export default class Skapi {
|
|
|
2693
2657
|
*/
|
|
2694
2658
|
async resendSignupConfirmation(
|
|
2695
2659
|
/** Redirect url on confirmation success. */
|
|
2696
|
-
redirect:
|
|
2660
|
+
redirect: string
|
|
2697
2661
|
): Promise<string> {
|
|
2698
|
-
if (
|
|
2699
|
-
|
|
2700
|
-
}
|
|
2701
|
-
|
|
2702
|
-
else if (typeof redirect !== 'boolean') {
|
|
2703
|
-
throw new SkapiError('Argument should be type: <boolean | string>.', { code: 'INVALID_REQUEST' });
|
|
2662
|
+
if (!this.__request_signup_confirmation) {
|
|
2663
|
+
throw new SkapiError('Least one login attempt is required.', { code: 'INVALID_REQUEST' });
|
|
2704
2664
|
}
|
|
2705
2665
|
|
|
2706
|
-
if (
|
|
2707
|
-
|
|
2666
|
+
if (redirect) {
|
|
2667
|
+
validateUrl(redirect);
|
|
2708
2668
|
}
|
|
2709
2669
|
|
|
2710
2670
|
let resend = await this.request("confirm-signup", {
|
|
@@ -2713,7 +2673,7 @@ export default class Skapi {
|
|
|
2713
2673
|
});
|
|
2714
2674
|
|
|
2715
2675
|
this.__request_signup_confirmation = null;
|
|
2716
|
-
return resend;
|
|
2676
|
+
return resend; // 'SUCCESS: Signup confirmation E-Mail has been sent.'
|
|
2717
2677
|
}
|
|
2718
2678
|
|
|
2719
2679
|
/**
|
|
@@ -2805,8 +2765,8 @@ export default class Skapi {
|
|
|
2805
2765
|
if (code) {
|
|
2806
2766
|
this.authentication().updateSession({ refreshToken: true }).then(
|
|
2807
2767
|
() => {
|
|
2808
|
-
if (this.
|
|
2809
|
-
this.
|
|
2768
|
+
if (this.__user) {
|
|
2769
|
+
this.__user[attribute + '_verified'] = true;
|
|
2810
2770
|
}
|
|
2811
2771
|
res(`SUCCESS: "${attribute}" is verified.`);
|
|
2812
2772
|
}
|
|
@@ -3020,8 +2980,8 @@ export default class Skapi {
|
|
|
3020
2980
|
async disableAccount(): Promise<string> {
|
|
3021
2981
|
await this.__connection;
|
|
3022
2982
|
|
|
3023
|
-
if (this.
|
|
3024
|
-
for (let s of this.
|
|
2983
|
+
if (this.__user && Array.isArray(this.__user.services)) {
|
|
2984
|
+
for (let s of this.__user.services) {
|
|
3025
2985
|
if (s.active) {
|
|
3026
2986
|
throw new SkapiError('All services needs to be disabled.', { code: 'INVALID_REQUEST' });
|
|
3027
2987
|
}
|
|
@@ -3086,7 +3046,7 @@ export default class Skapi {
|
|
|
3086
3046
|
});
|
|
3087
3047
|
|
|
3088
3048
|
if (params && typeof params === 'object' && !Object.keys(params).length) {
|
|
3089
|
-
return this.
|
|
3049
|
+
return this.__user;
|
|
3090
3050
|
}
|
|
3091
3051
|
|
|
3092
3052
|
if (params.new_password || params.current_password) {
|
|
@@ -3129,10 +3089,10 @@ export default class Skapi {
|
|
|
3129
3089
|
['phone_number_public', 'phone_number_verified', "User's phone number should be verified to set"]
|
|
3130
3090
|
];
|
|
3131
3091
|
|
|
3132
|
-
if (this.
|
|
3092
|
+
if (this.__user) {
|
|
3133
3093
|
for (let c of collision) {
|
|
3134
|
-
if (params[c[0]] && !this.
|
|
3135
|
-
throw new SkapiError(`${c[2]} "${c[0]}" to true.`, { code: '
|
|
3094
|
+
if (params[c[0]] && !this.__user[c[1]]) {
|
|
3095
|
+
throw new SkapiError(`${c[2]} "${c[0]}" to true.`, { code: 'INVALID_REQUEST' });
|
|
3136
3096
|
}
|
|
3137
3097
|
}
|
|
3138
3098
|
}
|
|
@@ -3191,7 +3151,7 @@ export default class Skapi {
|
|
|
3191
3151
|
await this.authentication().updateSession({ refreshToken: true });
|
|
3192
3152
|
}
|
|
3193
3153
|
|
|
3194
|
-
return this.
|
|
3154
|
+
return this.__user;
|
|
3195
3155
|
}
|
|
3196
3156
|
|
|
3197
3157
|
|
|
@@ -3242,7 +3202,7 @@ export default class Skapi {
|
|
|
3242
3202
|
|
|
3243
3203
|
await this.request('post-userdata', form, opt);
|
|
3244
3204
|
await this.authentication().updateSession();
|
|
3245
|
-
return this.
|
|
3205
|
+
return this.__user;
|
|
3246
3206
|
}
|
|
3247
3207
|
|
|
3248
3208
|
/**
|
|
@@ -3478,7 +3438,7 @@ export default class Skapi {
|
|
|
3478
3438
|
|
|
3479
3439
|
let user = result.list[0];
|
|
3480
3440
|
// append user session data
|
|
3481
|
-
Object.assign(user, this.
|
|
3441
|
+
Object.assign(user, this.__user);
|
|
3482
3442
|
|
|
3483
3443
|
user._what_public_see = JSON.parse(JSON.stringify(user));
|
|
3484
3444
|
|
package/src/utils.ts
CHANGED
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
import SkapiError from "./skapi_error";
|
|
2
2
|
import { RecordData, Form } from "./Types";
|
|
3
3
|
|
|
4
|
-
const sha256: any = function (ascii) {
|
|
5
|
-
// author: https://geraintluff.github.io/sha256/
|
|
6
|
-
|
|
4
|
+
const sha256: any = function sha256(ascii) {
|
|
7
5
|
function rightRotate(value, amount) {
|
|
8
6
|
return (value >>> amount) | (value << (32 - amount));
|
|
9
7
|
};
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
let mathPow = Math.pow;
|
|
10
|
+
let maxWord = mathPow(2, 32);
|
|
11
|
+
let lengthProperty = 'length';
|
|
12
|
+
let i, j; // Used as a counter across the whole file
|
|
13
|
+
let result = '';
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
let words = [];
|
|
16
|
+
let asciiBitLength = ascii[lengthProperty] * 8;
|
|
19
17
|
|
|
20
18
|
//* caching results is optional - remove/add slash from front of this line to toggle
|
|
21
19
|
// Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes
|
|
22
20
|
// (we actually calculate the first 64, but extra values are just ignored)
|
|
23
|
-
|
|
21
|
+
let hash = (sha256 as any).h = (sha256 as any).h || [];
|
|
24
22
|
// Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
let k = (sha256 as any).k = (sha256 as any).k || [];
|
|
24
|
+
let primeCounter = k[lengthProperty];
|
|
27
25
|
/*/
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
let hash = [], k = [];
|
|
27
|
+
let primeCounter = 0;
|
|
30
28
|
//*/
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
for (
|
|
30
|
+
let isComposite = {};
|
|
31
|
+
for (let candidate = 2; primeCounter < 64; candidate++) {
|
|
34
32
|
if (!isComposite[candidate]) {
|
|
35
33
|
for (i = 0; i < 313; i += candidate) {
|
|
36
34
|
isComposite[i] = candidate;
|
|
@@ -44,7 +42,9 @@ const sha256: any = function (ascii) {
|
|
|
44
42
|
while (ascii[lengthProperty] % 64 - 56) ascii += '\x00'; // More zero padding
|
|
45
43
|
for (i = 0; i < ascii[lengthProperty]; i++) {
|
|
46
44
|
j = ascii.charCodeAt(i);
|
|
47
|
-
if (j >> 8)
|
|
45
|
+
if (j >> 8) {
|
|
46
|
+
return; // ASCII check: only accept characters in range 0-255
|
|
47
|
+
}
|
|
48
48
|
words[i >> 2] |= j << ((3 - i) % 4) * 8;
|
|
49
49
|
}
|
|
50
50
|
words[words[lengthProperty]] = ((asciiBitLength / maxWord) | 0);
|
|
@@ -52,21 +52,21 @@ const sha256: any = function (ascii) {
|
|
|
52
52
|
|
|
53
53
|
// process each chunk
|
|
54
54
|
for (j = 0; j < words[lengthProperty];) {
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
let w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration
|
|
56
|
+
let oldHash = hash;
|
|
57
57
|
// This is now the undefinedworking hash", often labelled as variables a...g
|
|
58
58
|
// (we have to truncate as well, otherwise extra entries at the end accumulate
|
|
59
59
|
hash = hash.slice(0, 8);
|
|
60
60
|
|
|
61
61
|
for (i = 0; i < 64; i++) {
|
|
62
|
-
|
|
62
|
+
let i2 = i + j;
|
|
63
63
|
// Expand the message into 64 words
|
|
64
64
|
// Used below if
|
|
65
|
-
|
|
65
|
+
let w15 = w[i - 15], w2 = w[i - 2];
|
|
66
66
|
|
|
67
67
|
// Iterate
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
let a = hash[0], e = hash[4];
|
|
69
|
+
let temp1 = hash[7]
|
|
70
70
|
+ (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
|
|
71
71
|
+ ((e & hash[5]) ^ ((~e) & hash[6])) // ch
|
|
72
72
|
+ k[i]
|
|
@@ -79,7 +79,7 @@ const sha256: any = function (ascii) {
|
|
|
79
79
|
) | 0
|
|
80
80
|
);
|
|
81
81
|
// This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble
|
|
82
|
-
|
|
82
|
+
let temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
|
|
83
83
|
+ ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2])); // maj
|
|
84
84
|
|
|
85
85
|
hash = [(temp1 + temp2) | 0].concat(hash); // We don't bother trimming off the extra ones, they're harmless as long as we're truncating when we do the slice()
|
|
@@ -93,10 +93,11 @@ const sha256: any = function (ascii) {
|
|
|
93
93
|
|
|
94
94
|
for (i = 0; i < 8; i++) {
|
|
95
95
|
for (j = 3; j + 1; j--) {
|
|
96
|
-
|
|
96
|
+
let b = (hash[i] >> (j * 8)) & 255;
|
|
97
97
|
result += ((b < 16) ? 0 : '') + b.toString(16);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
+
|
|
100
101
|
return result;
|
|
101
102
|
};
|
|
102
103
|
|
|
@@ -236,7 +237,7 @@ function checkParams(
|
|
|
236
237
|
} catch (err) {
|
|
237
238
|
if (typeof err === 'string' && err.substring(0, 6) === 'BREAK:') {
|
|
238
239
|
// break on BREAK message
|
|
239
|
-
err = err.substring(
|
|
240
|
+
err = err.substring(6);
|
|
240
241
|
let errMsg = (err as string).split(':');
|
|
241
242
|
errToThrow = new SkapiError(errMsg[1], { code: errMsg[0] });
|
|
242
243
|
break;
|
|
@@ -291,6 +292,9 @@ function checkParams(
|
|
|
291
292
|
|
|
292
293
|
val = _params;
|
|
293
294
|
}
|
|
295
|
+
else {
|
|
296
|
+
throw new SkapiError(`Value: ${_params}${isInvalid}`, { code: 'INVALID_PARAMETER' });
|
|
297
|
+
}
|
|
294
298
|
}
|
|
295
299
|
|
|
296
300
|
else if (struct === null) {
|
package/tsconfig.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
24
24
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
25
25
|
/* Language and Environment */
|
|
26
|
-
"target": "
|
|
26
|
+
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
27
27
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
28
28
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
29
29
|
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
38
38
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
39
39
|
/* Modules */
|
|
40
|
-
"module": "
|
|
40
|
+
"module": "ES2020", /* Specify what module code is generated. */
|
|
41
41
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
42
42
|
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
43
43
|
"moduleResolution": "node",
|
package/webpack.config.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
module.exports = {
|
|
2
|
+
module.exports = [{
|
|
3
|
+
// cdn
|
|
3
4
|
mode: 'production',
|
|
4
5
|
target: 'web',
|
|
5
|
-
// target: 'node',
|
|
6
|
-
// externals: [nodeExternals()], // removes node_modules from your final bundle
|
|
7
6
|
entry: './js/Api.js',
|
|
8
7
|
output: {
|
|
9
|
-
// path: path.join(__dirname, 'bundle'),
|
|
10
8
|
filename: 'skapi.js',
|
|
11
9
|
libraryTarget: 'umd'
|
|
12
|
-
// libraryTarget: 'module'
|
|
13
10
|
},
|
|
14
|
-
// experiments: {
|
|
15
|
-
// outputModule: true
|
|
16
|
-
// },
|
|
17
|
-
// optimization: {
|
|
18
|
-
// minimize: true
|
|
19
|
-
// },
|
|
20
11
|
devtool: 'source-map'
|
|
21
|
-
}
|
|
12
|
+
}, {
|
|
13
|
+
// webpack
|
|
14
|
+
mode: 'production',
|
|
15
|
+
target: 'web',
|
|
16
|
+
entry: './js/Api.js',
|
|
17
|
+
output: {
|
|
18
|
+
filename: 'skapi.module.js',
|
|
19
|
+
libraryTarget: 'module'
|
|
20
|
+
},
|
|
21
|
+
experiments: {
|
|
22
|
+
outputModule: true
|
|
23
|
+
},
|
|
24
|
+
devtool: 'source-map'
|
|
25
|
+
}];
|