skapi-js 0.0.46 → 0.0.47

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skapi-js",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "skapi serverless cloud javascript library",
5
5
  "main": "./dist/skapi.module.js",
6
6
  "scripts": {
package/src/decorators.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Form, FormCallbacks } from './Types';
2
2
  import SkapiError from './skapi_error';
3
- import { sha256 } from './utils';
3
+ import { MD5 } from './utils';
4
4
 
5
5
  function formResponse() {
6
6
  // wraps methods that requires form handling
@@ -29,8 +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);
33
- let response_key = form.action;
32
+ let response_key = MD5.hash(form.action);
33
+ // let response_key = form.action;
34
34
  let timestamp = Date.now().toString();
35
35
 
36
36
  window.sessionStorage.setItem(response_key, JSON.stringify({ [timestamp]: response }));
package/src/skapi.ts CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  validateUrl,
35
35
  normalize_record_data,
36
36
  checkWhiteSpaceAndSpecialChars,
37
- sha256
37
+ MD5
38
38
  } from './utils';
39
39
 
40
40
  type StartKeys = {
@@ -1157,10 +1157,10 @@ export default class Skapi {
1157
1157
  return _obj;
1158
1158
  }
1159
1159
 
1160
- return url + '/' + JSON.stringify(orderObjectKeys(params));
1160
+ return MD5.hash(url + '/' + JSON.stringify(orderObjectKeys(params)));
1161
1161
  }
1162
1162
 
1163
- return url + '/' + this.service;
1163
+ return MD5.hash(url + '/' + this.service);
1164
1164
 
1165
1165
  })();
1166
1166
 
@@ -1175,8 +1175,8 @@ export default class Skapi {
1175
1175
  if (Array.isArray(this.__startKey_keys[url][hashedParams]) && this.__startKey_keys[url][hashedParams].length) {
1176
1176
  // delete cache of all startkeys
1177
1177
  for (let p of this.__startKey_keys[url][hashedParams]) {
1178
- // let hashedParams_cached = hashedParams + '/' + sha256(JSON.stringify(p));
1179
- let hashedParams_cached = hashedParams + '/' + JSON.stringify(p);
1178
+ let hashedParams_cached = hashedParams + '/' + MD5.hash(JSON.stringify(p));
1179
+ // let hashedParams_cached = hashedParams + '/' + JSON.stringify(p);
1180
1180
  // let hashedParams_cached = hashedParams + createHash('sha256').update(JSON.stringify(p)).digest('hex');
1181
1181
 
1182
1182
  if (this.__cached_requests?.[url] && this.__cached_requests?.[url]?.[hashedParams_cached]) {
@@ -1214,8 +1214,8 @@ export default class Skapi {
1214
1214
 
1215
1215
  else {
1216
1216
  // cache_hashedParams += createHash('sha256').update(last_startKey_key).digest('hex');
1217
- // cache_hashedParams += sha256(last_startKey_key);
1218
- cache_hashedParams += ('/' + last_startKey_key);
1217
+ cache_hashedParams += MD5.hash(last_startKey_key);
1218
+ // cache_hashedParams += ('/' + last_startKey_key);
1219
1219
  params.startKey = JSON.parse(last_startKey_key);
1220
1220
  }
1221
1221
  }
@@ -1437,7 +1437,7 @@ export default class Skapi {
1437
1437
  if (!option) {
1438
1438
  throw new SkapiError(['INVALID_PARAMETER', '"option" argument is required.']);
1439
1439
  }
1440
-
1440
+
1441
1441
  let { formData } = option;
1442
1442
  let fetchOptions: Record<string, any> = {};
1443
1443
 
package/src/utils.ts CHANGED
@@ -1,105 +1,163 @@
1
1
  import SkapiError from "./skapi_error";
2
2
  import { RecordData, Form } from "./Types";
3
3
 
4
- const sha256: any = function sha256(ascii) {
5
- function rightRotate(value, amount) {
6
- return (value >>> amount) | (value << (32 - amount));
7
- };
4
+ class MD5 {
5
+ private static readonly alphabet = '0123456789abcdef';
6
+
7
+ public static hash(str?: string): string {
8
+ if (typeof str !== 'string') {
9
+ console.warn('coercing non-string value to empty string');
10
+ str = '';
11
+ }
12
+
13
+ const x = MD5.sb(str);
14
+ let a = 1732584193;
15
+ let b = -271733879;
16
+ let c = -1732584194;
17
+ let d = 271733878;
18
+ let lastA;
19
+ let lastB;
20
+ let lastC;
21
+ let lastD;
22
+ for (let i = 0; i < x.length; i += 16) {
23
+ lastA = a;
24
+ lastB = b;
25
+ lastC = c;
26
+ lastD = d;
27
+
28
+ a = MD5.ff(a, b, c, d, x[i], 7, -680876936);
29
+ d = MD5.ff(d, a, b, c, x[i + 1], 12, -389564586);
30
+ c = MD5.ff(c, d, a, b, x[i + 2], 17, 606105819);
31
+ b = MD5.ff(b, c, d, a, x[i + 3], 22, -1044525330);
32
+ a = MD5.ff(a, b, c, d, x[i + 4], 7, -176418897);
33
+ d = MD5.ff(d, a, b, c, x[i + 5], 12, 1200080426);
34
+ c = MD5.ff(c, d, a, b, x[i + 6], 17, -1473231341);
35
+ b = MD5.ff(b, c, d, a, x[i + 7], 22, -45705983);
36
+ a = MD5.ff(a, b, c, d, x[i + 8], 7, 1770035416);
37
+ d = MD5.ff(d, a, b, c, x[i + 9], 12, -1958414417);
38
+ c = MD5.ff(c, d, a, b, x[i + 10], 17, -42063);
39
+ b = MD5.ff(b, c, d, a, x[i + 11], 22, -1990404162);
40
+ a = MD5.ff(a, b, c, d, x[i + 12], 7, 1804603682);
41
+ d = MD5.ff(d, a, b, c, x[i + 13], 12, -40341101);
42
+ c = MD5.ff(c, d, a, b, x[i + 14], 17, -1502002290);
43
+ b = MD5.ff(b, c, d, a, x[i + 15], 22, 1236535329);
44
+ a = MD5.gg(a, b, c, d, x[i + 1], 5, -165796510);
45
+ d = MD5.gg(d, a, b, c, x[i + 6], 9, -1069501632);
46
+ c = MD5.gg(c, d, a, b, x[i + 11], 14, 643717713);
47
+ b = MD5.gg(b, c, d, a, x[i], 20, -373897302);
48
+ a = MD5.gg(a, b, c, d, x[i + 5], 5, -701558691);
49
+ d = MD5.gg(d, a, b, c, x[i + 10], 9, 38016083);
50
+ c = MD5.gg(c, d, a, b, x[i + 15], 14, -660478335);
51
+ b = MD5.gg(b, c, d, a, x[i + 4], 20, -405537848);
52
+ a = MD5.gg(a, b, c, d, x[i + 9], 5, 568446438);
53
+ d = MD5.gg(d, a, b, c, x[i + 14], 9, -1019803690);
54
+ c = MD5.gg(c, d, a, b, x[i + 3], 14, -187363961);
55
+ b = MD5.gg(b, c, d, a, x[i + 8], 20, 1163531501);
56
+ a = MD5.gg(a, b, c, d, x[i + 13], 5, -1444681467);
57
+ d = MD5.gg(d, a, b, c, x[i + 2], 9, -51403784);
58
+ c = MD5.gg(c, d, a, b, x[i + 7], 14, 1735328473);
59
+ b = MD5.gg(b, c, d, a, x[i + 12], 20, -1926607734);
60
+ a = MD5.hh(a, b, c, d, x[i + 5], 4, -378558);
61
+ d = MD5.hh(d, a, b, c, x[i + 8], 11, -2022574463);
62
+ c = MD5.hh(c, d, a, b, x[i + 11], 16, 1839030562);
63
+ b = MD5.hh(b, c, d, a, x[i + 14], 23, -35309556);
64
+ a = MD5.hh(a, b, c, d, x[i + 1], 4, -1530992060);
65
+ d = MD5.hh(d, a, b, c, x[i + 4], 11, 1272893353);
66
+ c = MD5.hh(c, d, a, b, x[i + 7], 16, -155497632);
67
+ b = MD5.hh(b, c, d, a, x[i + 10], 23, -1094730640);
68
+ a = MD5.hh(a, b, c, d, x[i + 13], 4, 681279174);
69
+ d = MD5.hh(d, a, b, c, x[i], 11, -358537222);
70
+ c = MD5.hh(c, d, a, b, x[i + 3], 16, -722521979);
71
+ b = MD5.hh(b, c, d, a, x[i + 6], 23, 76029189);
72
+ a = MD5.hh(a, b, c, d, x[i + 9], 4, -640364487);
73
+ d = MD5.hh(d, a, b, c, x[i + 12], 11, -421815835);
74
+ c = MD5.hh(c, d, a, b, x[i + 15], 16, 530742520);
75
+ b = MD5.hh(b, c, d, a, x[i + 2], 23, -995338651);
76
+ a = MD5.ii(a, b, c, d, x[i], 6, -198630844);
77
+ d = MD5.ii(d, a, b, c, x[i + 7], 10, 1126891415);
78
+ c = MD5.ii(c, d, a, b, x[i + 14], 15, -1416354905);
79
+ b = MD5.ii(b, c, d, a, x[i + 5], 21, -57434055);
80
+ a = MD5.ii(a, b, c, d, x[i + 12], 6, 1700485571);
81
+ d = MD5.ii(d, a, b, c, x[i + 3], 10, -1894986606);
82
+ c = MD5.ii(c, d, a, b, x[i + 10], 15, -1051523);
83
+ b = MD5.ii(b, c, d, a, x[i + 1], 21, -2054922799);
84
+ a = MD5.ii(a, b, c, d, x[i + 8], 6, 1873313359);
85
+ d = MD5.ii(d, a, b, c, x[i + 15], 10, -30611744);
86
+ c = MD5.ii(c, d, a, b, x[i + 6], 15, -1560198380);
87
+ b = MD5.ii(b, c, d, a, x[i + 13], 21, 1309151649);
88
+ a = MD5.ii(a, b, c, d, x[i + 4], 6, -145523070);
89
+ d = MD5.ii(d, a, b, c, x[i + 11], 10, -1120210379);
90
+ c = MD5.ii(c, d, a, b, x[i + 2], 15, 718787259);
91
+ b = MD5.ii(b, c, d, a, x[i + 9], 21, -343485551);
92
+
93
+ a = MD5.ad(a, lastA);
94
+ b = MD5.ad(b, lastB);
95
+ c = MD5.ad(c, lastC);
96
+ d = MD5.ad(d, lastD);
97
+ }
98
+
99
+ return MD5.rh(a) + MD5.rh(b) + MD5.rh(c) + MD5.rh(d);
100
+ }
101
+
102
+ private static rh(n: number): string {
103
+ let s = '';
104
+ for (let j = 0; j <= 3; j++) {
105
+ s += MD5.alphabet.charAt((n >> (j * 8 + 4)) & 0x0F) + MD5.alphabet.charAt((n >> (j * 8)) & 0x0F);
106
+ }
107
+
108
+ return s;
109
+ }
110
+
111
+ private static ad(x: number, y: number): number {
112
+ const l = (x & 0xFFFF) + (y & 0xFFFF);
113
+ const m = (x >> 16) + (y >> 16) + (l >> 16);
114
+
115
+ return (m << 16) | (l & 0xFFFF);
116
+ }
117
+
118
+ private static rl(n: number, c: number): number {
119
+ return (n << c) | (n >>> (32 - c));
120
+ }
121
+
122
+ private static cm(q: number, a: number, b: number, x: number, s: number, t: number): number {
123
+ return MD5.ad(MD5.rl(MD5.ad(MD5.ad(a, q), MD5.ad(x, t)), s), b);
124
+ }
125
+
126
+ private static ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
127
+ return MD5.cm(b & c | ~b & d, a, b, x, s, t);
128
+ }
129
+
130
+ private static gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
131
+ return MD5.cm(b & d | c & ~d, a, b, x, s, t);
132
+ }
8
133
 
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 = '';
14
-
15
- let words = [];
16
- let asciiBitLength = ascii[lengthProperty] * 8;
17
-
18
- //* caching results is optional - remove/add slash from front of this line to toggle
19
- // Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes
20
- // (we actually calculate the first 64, but extra values are just ignored)
21
- let hash = (sha256 as any).h = (sha256 as any).h || [];
22
- // Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes
23
- let k = (sha256 as any).k = (sha256 as any).k || [];
24
- let primeCounter = k[lengthProperty];
25
- /*/
26
- let hash = [], k = [];
27
- let primeCounter = 0;
28
- //*/
29
-
30
- let isComposite = {};
31
- for (let candidate = 2; primeCounter < 64; candidate++) {
32
- if (!isComposite[candidate]) {
33
- for (i = 0; i < 313; i += candidate) {
34
- isComposite[i] = candidate;
35
- }
36
- hash[primeCounter] = (mathPow(candidate, .5) * maxWord) | 0;
37
- k[primeCounter++] = (mathPow(candidate, 1 / 3) * maxWord) | 0;
38
- }
134
+ private static hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
135
+ return MD5.cm(b ^ c ^ d, a, b, x, s, t);
39
136
  }
40
137
 
41
- ascii += '\x80'; // Append Ƈ' bit (plus zero padding)
42
- while (ascii[lengthProperty] % 64 - 56) ascii += '\x00'; // More zero padding
43
- for (i = 0; i < ascii[lengthProperty]; i++) {
44
- j = ascii.charCodeAt(i);
45
- if (j >> 8) {
46
- return; // ASCII check: only accept characters in range 0-255
47
- }
48
- words[i >> 2] |= j << ((3 - i) % 4) * 8;
138
+ private static ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {
139
+ return MD5.cm(c ^ (b | ~d), a, b, x, s, t);
49
140
  }
50
- words[words[lengthProperty]] = ((asciiBitLength / maxWord) | 0);
51
- words[words[lengthProperty]] = (asciiBitLength);
52
-
53
- // process each chunk
54
- for (j = 0; j < words[lengthProperty];) {
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
- // This is now the undefinedworking hash", often labelled as variables a...g
58
- // (we have to truncate as well, otherwise extra entries at the end accumulate
59
- hash = hash.slice(0, 8);
60
-
61
- for (i = 0; i < 64; i++) {
62
- let i2 = i + j;
63
- // Expand the message into 64 words
64
- // Used below if
65
- let w15 = w[i - 15], w2 = w[i - 2];
66
141
 
67
- // Iterate
68
- let a = hash[0], e = hash[4];
69
- let temp1 = hash[7]
70
- + (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
71
- + ((e & hash[5]) ^ ((~e) & hash[6])) // ch
72
- + k[i]
73
- // Expand the message schedule if needed
74
- + (w[i] = (i < 16) ? w[i] : (
75
- w[i - 16]
76
- + (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15 >>> 3)) // s0
77
- + w[i - 7]
78
- + (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2 >>> 10)) // s1
79
- ) | 0
80
- );
81
- // This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble
82
- let temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
83
- + ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2])); // maj
142
+ private static sb(x: string): number[] {
143
+ let i;
144
+ const numBlocks = ((x.length + 8) >> 6) + 1;
84
145
 
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()
86
- hash[4] = (hash[4] + temp1) | 0;
146
+ const blocks = new Array(numBlocks * 16);
147
+ for (i = 0; i < numBlocks * 16; i++) {
148
+ blocks[i] = 0;
87
149
  }
88
150
 
89
- for (i = 0; i < 8; i++) {
90
- hash[i] = (hash[i] + oldHash[i]) | 0;
151
+ for (i = 0; i < x.length; i++) {
152
+ blocks[i >> 2] |= x.charCodeAt(i) << ((i % 4) * 8);
91
153
  }
92
- }
93
154
 
94
- for (i = 0; i < 8; i++) {
95
- for (j = 3; j + 1; j--) {
96
- let b = (hash[i] >> (j * 8)) & 255;
97
- result += ((b < 16) ? 0 : '') + b.toString(16);
98
- }
99
- }
155
+ blocks[i >> 2] |= 0x80 << ((i % 4) * 8);
156
+ blocks[numBlocks * 16 - 2] = x.length * 8;
100
157
 
101
- return result;
102
- };
158
+ return blocks;
159
+ }
160
+ }
103
161
 
104
162
  function checkParams(
105
163
  params: any,
@@ -566,14 +624,20 @@ function validateUrl(url: string | string[]) {
566
624
  }
567
625
 
568
626
  function normalize_record_data<T extends RecordData>(record: T): RecordData {
627
+ function base_decode(chars) {
628
+ let charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
629
+ return chars.split('').reverse().reduce((prev, curr, i) =>
630
+ prev + (charset.indexOf(curr) * (62 ** i)), 0);
631
+ }
569
632
  const output: Record<any, any> = {};
570
633
 
571
634
  const keys = {
572
635
  'rec': (r) => {
573
636
  if (!r) return;
574
637
  output.record_id = r;
575
- let base36timestamp = r.substring(0, 8);
576
- output.uploaded = parseInt(base36timestamp, 36);
638
+ let base62timestamp = r.substring(0, r.length - 9); // id: [base62 timestamp][random 5 char][suid]
639
+ let uploaded = base_decode(base62timestamp);
640
+ output.uploaded = uploaded;
577
641
  },
578
642
  'usr': (r) => {
579
643
  if (!r) return;
@@ -735,5 +799,5 @@ export {
735
799
  validatePassword,
736
800
  validatePhoneNumber,
737
801
  validateUrl,
738
- sha256
802
+ MD5
739
803
  };