skapi-js 1.0.0-alpha.9 → 1.0.1
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 +52 -55
- package/dist/skapi.js +1 -1
- package/dist/skapi.js.map +1 -1
- package/dist/skapi.module.js +1 -1
- package/dist/skapi.module.js.map +1 -1
- package/js/Types.d.ts +53 -53
- package/js/main/error.d.ts +1 -0
- package/js/main/error.js +1 -1
- package/js/main/skapi.d.ts +43 -29
- package/js/main/skapi.js +117 -37
- package/js/methods/database.d.ts +13 -9
- package/js/methods/database.js +309 -137
- package/js/methods/request.d.ts +1 -0
- package/js/methods/request.js +47 -24
- package/js/methods/subscription.d.ts +1 -2
- package/js/methods/subscription.js +24 -30
- package/js/methods/user.d.ts +13 -8
- package/js/methods/user.js +36 -18
- package/js/utils/utils.d.ts +1 -0
- package/js/utils/utils.js +17 -17
- package/js/utils/validator.js +26 -20
- package/package.json +1 -1
package/js/methods/request.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Form, FormSubmitCallback, FetchOptions, Connection } from '../Types';
|
|
2
2
|
export declare function getConnection(): Promise<Connection>;
|
|
3
3
|
export declare function request(url: string, data?: Form<any> | null, options?: {
|
|
4
|
+
noParams?: boolean;
|
|
4
5
|
fetchOptions?: FetchOptions & FormSubmitCallback;
|
|
5
6
|
auth?: boolean;
|
|
6
7
|
method?: string;
|
package/js/methods/request.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import SkapiError from '../main/error';
|
|
2
|
-
import { MD5 } from '../utils/utils';
|
|
2
|
+
import { MD5, generateRandom } from '../utils/utils';
|
|
3
3
|
import validator from '../utils/validator';
|
|
4
4
|
const __pendingRequest = {};
|
|
5
5
|
export function getConnection() {
|
|
@@ -74,6 +74,7 @@ export async function request(url, data = null, options) {
|
|
|
74
74
|
case 'refresh-cdn':
|
|
75
75
|
case 'request-newsletter-sender':
|
|
76
76
|
case 'set-404':
|
|
77
|
+
case 'subdomain-info':
|
|
77
78
|
return {
|
|
78
79
|
public: admin.admin_public,
|
|
79
80
|
private: admin.admin_private
|
|
@@ -119,14 +120,16 @@ export async function request(url, data = null, options) {
|
|
|
119
120
|
let fetchOptions = {};
|
|
120
121
|
let { fetchMore = false, progress } = options?.fetchOptions || {};
|
|
121
122
|
if (options?.fetchOptions && Object.keys(options.fetchOptions).length) {
|
|
122
|
-
let fetOpt =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
let fetOpt = {};
|
|
124
|
+
for (let k of ['limit', 'startKey', 'ascending']) {
|
|
125
|
+
if (options.fetchOptions.hasOwnProperty(k)) {
|
|
126
|
+
fetOpt[k] = options.fetchOptions[k];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
fetOpt = validator.Params(fetOpt, {
|
|
130
|
+
limit: 'number',
|
|
128
131
|
startKey: null,
|
|
129
|
-
ascending:
|
|
132
|
+
ascending: 'boolean'
|
|
130
133
|
});
|
|
131
134
|
if (fetOpt.hasOwnProperty('limit') && typeof fetOpt.limit === 'number') {
|
|
132
135
|
if (fetOpt.limit > 1000) {
|
|
@@ -222,7 +225,16 @@ export async function request(url, data = null, options) {
|
|
|
222
225
|
headers.Authorization = token;
|
|
223
226
|
}
|
|
224
227
|
if (meta) {
|
|
225
|
-
|
|
228
|
+
let meta_key = '__meta__' + generateRandom(16);
|
|
229
|
+
if (data instanceof FormData) {
|
|
230
|
+
headers["Content-Meta"] = window.btoa(encodeURIComponent(JSON.stringify({
|
|
231
|
+
meta_key: meta_key,
|
|
232
|
+
merge: 'data'
|
|
233
|
+
})));
|
|
234
|
+
data.set(meta_key, new Blob([JSON.stringify(meta)], {
|
|
235
|
+
type: 'application/json'
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
226
238
|
}
|
|
227
239
|
if (options.hasOwnProperty('contentType')) {
|
|
228
240
|
if (options?.contentType) {
|
|
@@ -240,7 +252,7 @@ export async function request(url, data = null, options) {
|
|
|
240
252
|
__pendingRequest[requestKey] = _post.bind(this)(endpoint, data, opt, progress);
|
|
241
253
|
}
|
|
242
254
|
else if (method === 'get') {
|
|
243
|
-
__pendingRequest[requestKey] = _get.bind(this)(endpoint, data, opt, progress);
|
|
255
|
+
__pendingRequest[requestKey] = _get.bind(this)(endpoint, data, opt, progress, options?.noParams);
|
|
244
256
|
}
|
|
245
257
|
try {
|
|
246
258
|
let response = await __pendingRequest[requestKey];
|
|
@@ -482,8 +494,8 @@ async function _post(url, params, option, progress) {
|
|
|
482
494
|
return _fetch.bind(this)(url, opt, progress);
|
|
483
495
|
}
|
|
484
496
|
;
|
|
485
|
-
async function _get(url, params, option, progress) {
|
|
486
|
-
if (params && typeof params === 'object' && Object.keys(params).length) {
|
|
497
|
+
async function _get(url, params, option, progress, noParams) {
|
|
498
|
+
if (params && typeof params === 'object' && !noParams && Object.keys(params).length) {
|
|
487
499
|
if (url.substring(url.length - 1) !== '?') {
|
|
488
500
|
url = url + '?';
|
|
489
501
|
}
|
|
@@ -571,10 +583,12 @@ export function formHandler(options) {
|
|
|
571
583
|
}
|
|
572
584
|
const handleResponse = (response) => {
|
|
573
585
|
if (option?.response) {
|
|
574
|
-
if (typeof option.response === 'function')
|
|
586
|
+
if (typeof option.response === 'function') {
|
|
575
587
|
return option.response(response);
|
|
576
|
-
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
577
590
|
throw new SkapiError('Callback "response" should be type: function.', { code: 'INVALID_PARAMETER' });
|
|
591
|
+
}
|
|
578
592
|
}
|
|
579
593
|
if (formEl) {
|
|
580
594
|
if (routeWithDataKey) {
|
|
@@ -589,14 +603,21 @@ export function formHandler(options) {
|
|
|
589
603
|
if (form instanceof SubmitEvent) {
|
|
590
604
|
form.preventDefault();
|
|
591
605
|
}
|
|
592
|
-
|
|
606
|
+
if (err instanceof SkapiError) {
|
|
607
|
+
err.name = propertyKey + '()';
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
err = err instanceof Error ? err : new SkapiError(err, { name: propertyKey + '()' });
|
|
611
|
+
}
|
|
593
612
|
if (option?.onerror) {
|
|
594
|
-
if (typeof option.onerror === 'function')
|
|
595
|
-
return option.onerror(
|
|
596
|
-
|
|
597
|
-
|
|
613
|
+
if (typeof option.onerror === 'function') {
|
|
614
|
+
return option.onerror(err);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
return new SkapiError('Callback "onerror" should be type: function.', { code: 'INVALID_PARAMETER', name: propertyKey + '()' });
|
|
618
|
+
}
|
|
598
619
|
}
|
|
599
|
-
|
|
620
|
+
return err;
|
|
600
621
|
};
|
|
601
622
|
const executeMethod = () => {
|
|
602
623
|
try {
|
|
@@ -616,7 +637,11 @@ export function formHandler(options) {
|
|
|
616
637
|
return handleResponse(resolved);
|
|
617
638
|
}
|
|
618
639
|
catch (err) {
|
|
619
|
-
|
|
640
|
+
let is_err = handleError(err);
|
|
641
|
+
if (is_err instanceof Error) {
|
|
642
|
+
throw is_err;
|
|
643
|
+
}
|
|
644
|
+
return is_err;
|
|
620
645
|
}
|
|
621
646
|
})();
|
|
622
647
|
}
|
|
@@ -624,9 +649,7 @@ export function formHandler(options) {
|
|
|
624
649
|
if (preventMultipleCalls) {
|
|
625
650
|
return (async () => {
|
|
626
651
|
if (pendPromise?.[propertyKey] instanceof Promise) {
|
|
627
|
-
|
|
628
|
-
pendPromise[propertyKey] = null;
|
|
629
|
-
return res;
|
|
652
|
+
return pendPromise[propertyKey];
|
|
630
653
|
}
|
|
631
654
|
else {
|
|
632
655
|
pendPromise[propertyKey] = executeMethod().finally(() => {
|
|
@@ -2,7 +2,6 @@ import { DatabaseResponse, FetchOptions, Form, Newsletters, SubscriptionGroup }
|
|
|
2
2
|
export declare function getSubscriptions(params: {
|
|
3
3
|
subscriber?: string;
|
|
4
4
|
subscription?: string;
|
|
5
|
-
group?: number;
|
|
6
5
|
blocked?: boolean;
|
|
7
6
|
}, fetchOptions?: FetchOptions, _mapper?: Function): Promise<DatabaseResponse<{
|
|
8
7
|
subscriber: string;
|
|
@@ -22,7 +21,7 @@ export declare function getSubscribers(option: SubscriptionGroup<number | undefi
|
|
|
22
21
|
blocked?: boolean;
|
|
23
22
|
}, fetchOptions: FetchOptions): Promise<DatabaseResponse<any>>;
|
|
24
23
|
export declare function getNewsletterSubscription(params: {
|
|
25
|
-
group?: number;
|
|
24
|
+
group?: number | 'public' | 'authorized';
|
|
26
25
|
}): Promise<{
|
|
27
26
|
active: boolean;
|
|
28
27
|
timestamp: number;
|
|
@@ -4,19 +4,7 @@ import { request } from './request';
|
|
|
4
4
|
function subscriptionGroupCheck(option) {
|
|
5
5
|
option = validator.Params(option, {
|
|
6
6
|
user_id: (v) => validator.UserId(v, '"user_id"'),
|
|
7
|
-
|
|
8
|
-
if (v === '*') {
|
|
9
|
-
return v;
|
|
10
|
-
}
|
|
11
|
-
if (typeof v !== 'number') {
|
|
12
|
-
throw new SkapiError('"group" should be type: number.', { code: 'INVALID_PARAMETER' });
|
|
13
|
-
}
|
|
14
|
-
else if (v < 1 && v > 99) {
|
|
15
|
-
throw new SkapiError('"group" should be within range 1 ~ 99.', { code: 'INVALID_PARAMETER' });
|
|
16
|
-
}
|
|
17
|
-
return v;
|
|
18
|
-
}
|
|
19
|
-
}, ['user_id', 'group']);
|
|
7
|
+
}, ['user_id']);
|
|
20
8
|
if (this.__user && option.user_id === this.__user.user_id) {
|
|
21
9
|
throw new SkapiError(`"user_id" cannot be the user's own ID.`, { code: 'INVALID_PARAMETER' });
|
|
22
10
|
}
|
|
@@ -26,13 +14,13 @@ function subscriptionGroupCheck(option) {
|
|
|
26
14
|
export async function getSubscriptions(params, fetchOptions, _mapper) {
|
|
27
15
|
params = validator.Params(params, {
|
|
28
16
|
subscriber: (v) => validator.UserId(v, 'User ID in "subscriber"'),
|
|
29
|
-
group: 'number',
|
|
30
17
|
subscription: (v) => validator.UserId(v, 'User ID in "subscription"'),
|
|
31
18
|
blocked: 'boolean'
|
|
32
19
|
});
|
|
33
20
|
if (!params.subscriber && !params.subscription) {
|
|
34
21
|
throw new SkapiError('At least either "subscriber" or "subscription" should have a value.', { code: 'INVALID_PARAMETER' });
|
|
35
22
|
}
|
|
23
|
+
Object.assign(params, { group: 1 });
|
|
36
24
|
let response = await request.bind(this)('get-subscription', params, Object.assign({ auth: true }, { fetchOptions }));
|
|
37
25
|
response.list = response.list.map(_mapper || ((s) => {
|
|
38
26
|
let subscription = {};
|
|
@@ -48,43 +36,39 @@ export async function getSubscriptions(params, fetchOptions, _mapper) {
|
|
|
48
36
|
}
|
|
49
37
|
export async function subscribe(option) {
|
|
50
38
|
await this.__connection;
|
|
51
|
-
let { user_id
|
|
52
|
-
if (typeof group !== 'number') {
|
|
53
|
-
throw new SkapiError('"group" should be type: number.', { code: 'INVALID_PARAMETER' });
|
|
54
|
-
}
|
|
39
|
+
let { user_id } = subscriptionGroupCheck.bind(this)(option);
|
|
55
40
|
return await request.bind(this)('subscription', {
|
|
56
41
|
subscribe: user_id,
|
|
57
|
-
group
|
|
42
|
+
group: 1
|
|
58
43
|
}, { auth: true });
|
|
59
44
|
}
|
|
60
45
|
export async function unsubscribe(option) {
|
|
61
46
|
await this.__connection;
|
|
62
|
-
let { user_id
|
|
47
|
+
let { user_id } = subscriptionGroupCheck.bind(this)(option);
|
|
63
48
|
return await request.bind(this)('subscription', {
|
|
64
49
|
unsubscribe: user_id,
|
|
65
|
-
group
|
|
50
|
+
group: 1
|
|
66
51
|
}, { auth: true });
|
|
67
52
|
}
|
|
68
53
|
export async function blockSubscriber(option) {
|
|
69
54
|
await this.__connection;
|
|
70
|
-
let { user_id
|
|
71
|
-
return await request.bind(this)('subscription', { block: user_id, group }, { auth: true });
|
|
55
|
+
let { user_id } = subscriptionGroupCheck.bind(this)(option);
|
|
56
|
+
return await request.bind(this)('subscription', { block: user_id, group: 1 }, { auth: true });
|
|
72
57
|
}
|
|
73
58
|
export async function unblockSubscriber(option) {
|
|
74
59
|
await this.__connection;
|
|
75
|
-
let { user_id
|
|
76
|
-
return await request.bind(this)('subscription', { unblock: user_id, group }, { auth: true });
|
|
60
|
+
let { user_id } = subscriptionGroupCheck.bind(this)(option);
|
|
61
|
+
return await request.bind(this)('subscription', { unblock: user_id, group: 1 }, { auth: true });
|
|
77
62
|
}
|
|
78
63
|
export async function getSubscribedTo(option, fetchOptions) {
|
|
79
64
|
await this.__connection;
|
|
80
65
|
option = validator.Params(option, {
|
|
81
66
|
user_id: (v) => validator.UserId(v, '"user_id"'),
|
|
82
|
-
group: 'number',
|
|
83
67
|
blocked: 'boolean'
|
|
84
68
|
}) || {};
|
|
85
69
|
return getSubscriptions.bind(this)({
|
|
86
70
|
subscriber: option.user_id || this.__user?.user_id,
|
|
87
|
-
group:
|
|
71
|
+
group: 1,
|
|
88
72
|
blocked: option.blocked
|
|
89
73
|
}, fetchOptions);
|
|
90
74
|
}
|
|
@@ -93,12 +77,11 @@ export async function getSubscribers(option, fetchOptions) {
|
|
|
93
77
|
await this.__connection;
|
|
94
78
|
option = validator.Params(option, {
|
|
95
79
|
user_id: (v) => validator.UserId(v, '"user_id"'),
|
|
96
|
-
group: 'number',
|
|
97
80
|
blocked: 'boolean'
|
|
98
81
|
}) || {};
|
|
99
82
|
let subParams = {
|
|
100
83
|
subscription: option.user_id || this.__user?.user_id,
|
|
101
|
-
group:
|
|
84
|
+
group: 1,
|
|
102
85
|
blocked: option.blocked
|
|
103
86
|
};
|
|
104
87
|
return getSubscriptions.bind(this)(subParams, fetchOptions);
|
|
@@ -114,7 +97,18 @@ export async function getNewsletterSubscription(params) {
|
|
|
114
97
|
}
|
|
115
98
|
return v;
|
|
116
99
|
},
|
|
117
|
-
group:
|
|
100
|
+
group: v => {
|
|
101
|
+
if (v === 'public') {
|
|
102
|
+
v = 0;
|
|
103
|
+
}
|
|
104
|
+
if (v === 'authorized') {
|
|
105
|
+
v = 1;
|
|
106
|
+
}
|
|
107
|
+
if (typeof v !== 'number') {
|
|
108
|
+
throw new SkapiError('"group" should be type number | "public" | "authorized".', { code: 'INVALID_PARAMETER' });
|
|
109
|
+
}
|
|
110
|
+
return v;
|
|
111
|
+
}
|
|
118
112
|
});
|
|
119
113
|
let list = await request.bind(this)('get-newsletter-subscription', params, { auth: true });
|
|
120
114
|
let result = [];
|
package/js/methods/user.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CognitoUser, CognitoUserSession, CognitoUserPool } from 'amazon-cognito-identity-js';
|
|
2
|
-
import {
|
|
2
|
+
import { Form, FormSubmitCallback, UserProfile, FetchOptions, DatabaseResponse, UserAttributes, PublicUser } from '../Types';
|
|
3
3
|
export declare let userPool: CognitoUserPool | null;
|
|
4
4
|
export declare function setUserPool(params: {
|
|
5
5
|
UserPoolId: string;
|
|
@@ -9,7 +9,7 @@ export declare function authentication(): {
|
|
|
9
9
|
getSession: (option?: {
|
|
10
10
|
refreshToken?: boolean;
|
|
11
11
|
}) => Promise<CognitoUserSession>;
|
|
12
|
-
authenticateUser: (email: string, password: string) => Promise<
|
|
12
|
+
authenticateUser: (email: string, password: string) => Promise<UserProfile>;
|
|
13
13
|
createCognitoUser: (email: string) => Promise<{
|
|
14
14
|
cognitoUser: CognitoUser;
|
|
15
15
|
cognitoUsername: string;
|
|
@@ -18,16 +18,16 @@ export declare function authentication(): {
|
|
|
18
18
|
};
|
|
19
19
|
export declare function getProfile(options?: {
|
|
20
20
|
refreshToken: boolean;
|
|
21
|
-
}): Promise<
|
|
21
|
+
}): Promise<UserProfile | null>;
|
|
22
22
|
export declare function checkAdmin(): Promise<boolean>;
|
|
23
23
|
export declare function logout(): Promise<'SUCCESS: The user has been logged out.'>;
|
|
24
24
|
export declare function resendSignupConfirmation(redirect: string): Promise<'SUCCESS: Signup confirmation E-Mail has been sent.'>;
|
|
25
25
|
export declare function recoverAccount(redirect?: boolean | string): Promise<"SUCCESS: Recovery e-mail has been sent.">;
|
|
26
26
|
export declare function login(form: Form<{
|
|
27
|
-
username
|
|
27
|
+
username?: string;
|
|
28
28
|
email: string;
|
|
29
29
|
password: string;
|
|
30
|
-
}>): Promise<
|
|
30
|
+
}>): Promise<UserProfile>;
|
|
31
31
|
export declare function signup(form: Form<UserAttributes & {
|
|
32
32
|
email: String;
|
|
33
33
|
password: String;
|
|
@@ -35,7 +35,7 @@ export declare function signup(form: Form<UserAttributes & {
|
|
|
35
35
|
signup_confirmation?: boolean | string;
|
|
36
36
|
email_subscription?: boolean;
|
|
37
37
|
login?: boolean;
|
|
38
|
-
} & FormSubmitCallback): Promise<
|
|
38
|
+
} & FormSubmitCallback): Promise<UserProfile | "SUCCESS: The account has been created. User's signup confirmation is required." | 'SUCCESS: The account has been created.'>;
|
|
39
39
|
export declare function disableAccount(): Promise<'SUCCESS: account has been disabled.'>;
|
|
40
40
|
export declare function resetPassword(form: Form<{
|
|
41
41
|
email: string;
|
|
@@ -55,8 +55,13 @@ export declare function changePassword(params: {
|
|
|
55
55
|
new_password: string;
|
|
56
56
|
current_password: string;
|
|
57
57
|
}): Promise<'SUCCESS: Password has been changed.'>;
|
|
58
|
-
export declare function updateProfile(form: Form<UserAttributes>): Promise<
|
|
59
|
-
export declare function getUsers(params?:
|
|
58
|
+
export declare function updateProfile(form: Form<UserAttributes>): Promise<UserProfile>;
|
|
59
|
+
export declare function getUsers(params?: {
|
|
60
|
+
searchFor: string;
|
|
61
|
+
value: string | number | boolean;
|
|
62
|
+
condition?: '>' | '>=' | '=' | '<' | '<=' | '!=' | 'gt' | 'gte' | 'eq' | 'lt' | 'lte' | 'ne';
|
|
63
|
+
range?: string | number | boolean;
|
|
64
|
+
}, fetchOptions?: FetchOptions): Promise<DatabaseResponse<PublicUser>>;
|
|
60
65
|
export declare function lastVerifiedEmail(params?: {
|
|
61
66
|
revert: boolean;
|
|
62
67
|
}): Promise<string | UserProfile>;
|
package/js/methods/user.js
CHANGED
|
@@ -125,7 +125,7 @@ export function authentication() {
|
|
|
125
125
|
}
|
|
126
126
|
});
|
|
127
127
|
};
|
|
128
|
-
const getSession = (option) => {
|
|
128
|
+
const getSession = async (option) => {
|
|
129
129
|
let { refreshToken = false } = option || {};
|
|
130
130
|
return new Promise((res, rej) => {
|
|
131
131
|
cognitoUser = userPool?.getCurrentUser() || null;
|
|
@@ -206,18 +206,18 @@ export function authentication() {
|
|
|
206
206
|
this.__request_signup_confirmation = null;
|
|
207
207
|
this.__disabledAccount = null;
|
|
208
208
|
createCognitoUser(email).then(initUser => {
|
|
209
|
-
cognitoUser = initUser.cognitoUser;
|
|
210
209
|
let username = initUser.cognitoUsername;
|
|
211
210
|
let authenticationDetails = new AuthenticationDetails({
|
|
212
211
|
Username: username,
|
|
213
212
|
Password: password
|
|
214
213
|
});
|
|
215
|
-
cognitoUser.authenticateUser(authenticationDetails, {
|
|
214
|
+
initUser.cognitoUser.authenticateUser(authenticationDetails, {
|
|
216
215
|
newPasswordRequired: (userAttributes, requiredAttributes) => {
|
|
217
216
|
this.__request_signup_confirmation = username;
|
|
218
217
|
if (userAttributes['custom:signup_ticket'] === 'PASS' || userAttributes['custom:signup_ticket'] === 'MEMBER') {
|
|
219
|
-
cognitoUser.completeNewPasswordChallenge(password, {}, {
|
|
220
|
-
onSuccess:
|
|
218
|
+
initUser.cognitoUser.completeNewPasswordChallenge(password, {}, {
|
|
219
|
+
onSuccess: _ => {
|
|
220
|
+
cognitoUser = initUser.cognitoUser;
|
|
221
221
|
getSession().then(session => res(this.user));
|
|
222
222
|
},
|
|
223
223
|
onFailure: (err) => {
|
|
@@ -229,7 +229,9 @@ export function authentication() {
|
|
|
229
229
|
rej(new SkapiError("User's signup confirmation is required.", { code: 'SIGNUP_CONFIRMATION_NEEDED' }));
|
|
230
230
|
}
|
|
231
231
|
},
|
|
232
|
-
onSuccess:
|
|
232
|
+
onSuccess: _ => getSession().then(_ => {
|
|
233
|
+
res(this.user);
|
|
234
|
+
}),
|
|
233
235
|
onFailure: (err) => {
|
|
234
236
|
let error = [err.message || 'Failed to authenticate user.', err?.code || 'INVALID_REQUEST'];
|
|
235
237
|
if (err.code === "NotAuthorizedException") {
|
|
@@ -241,6 +243,12 @@ export function authentication() {
|
|
|
241
243
|
error = ['Incorrect username or password.', 'INCORRECT_USERNAME_OR_PASSWORD'];
|
|
242
244
|
}
|
|
243
245
|
}
|
|
246
|
+
else if (err.code === "UserNotFoundException") {
|
|
247
|
+
error = ['Incorrect username or password.', 'INCORRECT_USERNAME_OR_PASSWORD'];
|
|
248
|
+
}
|
|
249
|
+
else if (err.code === "TooManyRequestsException" || err.code === "LimitExceededException") {
|
|
250
|
+
error = ['Too many attempts. Please try again later.', 'REQUEST_EXCEED'];
|
|
251
|
+
}
|
|
244
252
|
let errCode = error[1];
|
|
245
253
|
let errMsg = error[0];
|
|
246
254
|
let customErr = error[0].split('#');
|
|
@@ -263,7 +271,7 @@ export function authentication() {
|
|
|
263
271
|
};
|
|
264
272
|
}
|
|
265
273
|
export async function getProfile(options) {
|
|
266
|
-
await this.
|
|
274
|
+
await this.__authConnection;
|
|
267
275
|
try {
|
|
268
276
|
await authentication.bind(this)().getSession(options);
|
|
269
277
|
return this.user;
|
|
@@ -316,7 +324,7 @@ export async function resendSignupConfirmation(redirect) {
|
|
|
316
324
|
}
|
|
317
325
|
export async function recoverAccount(redirect = false) {
|
|
318
326
|
if (typeof redirect === 'string') {
|
|
319
|
-
validator.Url(redirect);
|
|
327
|
+
redirect = validator.Url(redirect);
|
|
320
328
|
}
|
|
321
329
|
else if (typeof redirect !== 'boolean') {
|
|
322
330
|
throw new SkapiError('Argument should be type: <boolean | string>.', { code: 'INVALID_REQUEST' });
|
|
@@ -329,7 +337,7 @@ export async function recoverAccount(redirect = false) {
|
|
|
329
337
|
return 'SUCCESS: Recovery e-mail has been sent.';
|
|
330
338
|
}
|
|
331
339
|
export async function login(form) {
|
|
332
|
-
await logout
|
|
340
|
+
await this.logout();
|
|
333
341
|
let params = validator.Params(form, {
|
|
334
342
|
username: 'string',
|
|
335
343
|
email: (v) => validator.Email(v),
|
|
@@ -407,18 +415,23 @@ export async function signup(form, option) {
|
|
|
407
415
|
}
|
|
408
416
|
params.signup_confirmation = signup_confirmation;
|
|
409
417
|
params.email_subscription = option?.email_subscription || false;
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
418
|
+
if (!admin_creating_account) {
|
|
419
|
+
delete params.service;
|
|
420
|
+
delete params.owner;
|
|
421
|
+
}
|
|
422
|
+
let resp = await request.bind(this)("signup", params, { auth: admin_creating_account });
|
|
413
423
|
if (signup_confirmation) {
|
|
414
424
|
let u = await authentication.bind(this)().createCognitoUser(params.username || params.email);
|
|
415
425
|
cognitoUser = u.cognitoUser;
|
|
416
426
|
this.__request_signup_confirmation = u.cognitoUsername;
|
|
417
427
|
return "SUCCESS: The account has been created. User's signup confirmation is required.";
|
|
418
428
|
}
|
|
419
|
-
if (logUser) {
|
|
429
|
+
if (logUser && !admin_creating_account) {
|
|
420
430
|
return login.bind(this)({ email: params.username || params.email, password: params.password });
|
|
421
431
|
}
|
|
432
|
+
if (admin_creating_account) {
|
|
433
|
+
return resp;
|
|
434
|
+
}
|
|
422
435
|
return 'SUCCESS: The account has been created.';
|
|
423
436
|
}
|
|
424
437
|
export async function disableAccount() {
|
|
@@ -551,6 +564,9 @@ export async function changePassword(params) {
|
|
|
551
564
|
else if (err?.code === "NotAuthorizedException") {
|
|
552
565
|
rej(new SkapiError('Incorrect password.', { code: 'INVALID_REQUEST' }));
|
|
553
566
|
}
|
|
567
|
+
else if (err?.code === "TooManyRequestsException" || err?.code === "LimitExceededException") {
|
|
568
|
+
rej(new SkapiError('Too many attempts. Please try again later.', { code: 'REQUEST_EXCEED' }));
|
|
569
|
+
}
|
|
554
570
|
else {
|
|
555
571
|
rej(new SkapiError(err?.message || 'Failed to change user password.', { code: err?.code || err?.name }));
|
|
556
572
|
}
|
|
@@ -673,18 +689,18 @@ export async function getUsers(params, fetchOptions) {
|
|
|
673
689
|
}
|
|
674
690
|
const searchForTypes = {
|
|
675
691
|
'user_id': (v) => validator.UserId(v),
|
|
676
|
-
'name': 'string',
|
|
677
692
|
'email': (v) => validator.Email(v),
|
|
678
693
|
'phone_number': (v) => validator.PhoneNumber(v),
|
|
679
|
-
'address': 'string',
|
|
680
|
-
'gender': 'string',
|
|
681
|
-
'birthdate': (v) => validator.Birthdate(v),
|
|
682
694
|
'locale': (v) => {
|
|
683
695
|
if (typeof v !== 'string' || typeof v === 'string' && v.length > 5) {
|
|
684
696
|
throw new SkapiError('Value of "locale" should be a country code.', { code: 'INVALID_PARAMETER' });
|
|
685
697
|
}
|
|
686
698
|
return v;
|
|
687
699
|
},
|
|
700
|
+
'name': 'string',
|
|
701
|
+
'address': 'string',
|
|
702
|
+
'gender': 'string',
|
|
703
|
+
'birthdate': (v) => validator.Birthdate(v),
|
|
688
704
|
'timestamp': 'number',
|
|
689
705
|
'access_group': 'number',
|
|
690
706
|
'approved': (v) => {
|
|
@@ -716,7 +732,9 @@ export async function getUsers(params, fetchOptions) {
|
|
|
716
732
|
value: (v) => {
|
|
717
733
|
let checker = searchForTypes[params.searchFor];
|
|
718
734
|
if (typeof checker === 'function') {
|
|
719
|
-
|
|
735
|
+
if (!params?.condition || params?.condition === '=' || params?.range) {
|
|
736
|
+
return checker(v);
|
|
737
|
+
}
|
|
720
738
|
}
|
|
721
739
|
else if (typeof v !== checker) {
|
|
722
740
|
throw new SkapiError(`Value does not match the type of "${params.searchFor}" index.`, { code: 'INVALID_PARAMETER' });
|
package/js/utils/utils.d.ts
CHANGED
package/js/utils/utils.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import SkapiError from "../main/error";
|
|
2
1
|
class MD5 {
|
|
3
2
|
static hash(str) {
|
|
4
3
|
if (typeof str !== 'string') {
|
|
@@ -182,6 +181,7 @@ function extractFormMeta(form) {
|
|
|
182
181
|
meta[key] = val;
|
|
183
182
|
}
|
|
184
183
|
}
|
|
184
|
+
let to_bin = [];
|
|
185
185
|
if (form instanceof FormData) {
|
|
186
186
|
let meta = {};
|
|
187
187
|
let totalFileSize = 0;
|
|
@@ -190,18 +190,22 @@ function extractFormMeta(form) {
|
|
|
190
190
|
let name = pair[0];
|
|
191
191
|
let v = pair[1];
|
|
192
192
|
if (v instanceof File) {
|
|
193
|
-
if (
|
|
194
|
-
|
|
193
|
+
if ((totalFileSize + v.size) > 4000000) {
|
|
194
|
+
to_bin.push({ name, file: v });
|
|
195
|
+
continue;
|
|
195
196
|
}
|
|
196
197
|
totalFileSize += v.size;
|
|
198
|
+
files.push({ name, file: v });
|
|
197
199
|
}
|
|
198
200
|
else if (v instanceof FileList) {
|
|
199
|
-
if (!files.includes(name)) {
|
|
200
|
-
files.push(name);
|
|
201
|
-
}
|
|
202
201
|
if (v && v.length > 0) {
|
|
203
202
|
for (let idx = 0; idx <= v.length - 1; idx++) {
|
|
203
|
+
if ((totalFileSize + v.item(idx).size) > 4000000) {
|
|
204
|
+
to_bin.push({ name, file: v.item(idx) });
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
204
207
|
totalFileSize += v.item(idx).size;
|
|
208
|
+
files.push({ name, file: v.item(idx) });
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
}
|
|
@@ -209,10 +213,7 @@ function extractFormMeta(form) {
|
|
|
209
213
|
appendData(meta, name, v);
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
|
-
|
|
213
|
-
throw new SkapiError('Total File size cannot exceed 4MB. Use skapi.uploadFiles() instead.', { code: 'INVALID_REQUEST' });
|
|
214
|
-
}
|
|
215
|
-
return { meta, files };
|
|
216
|
+
return { meta, files, to_bin };
|
|
216
217
|
}
|
|
217
218
|
if (form instanceof SubmitEvent) {
|
|
218
219
|
form = form.target;
|
|
@@ -262,12 +263,14 @@ function extractFormMeta(form) {
|
|
|
262
263
|
}
|
|
263
264
|
}
|
|
264
265
|
else if (i.type === 'file') {
|
|
265
|
-
if (!files.includes(i.name)) {
|
|
266
|
-
files.push(i.name);
|
|
267
|
-
}
|
|
268
266
|
if (i.files && i.files.length > 0) {
|
|
269
267
|
for (let idx = 0; idx <= i.files.length - 1; idx++) {
|
|
268
|
+
if ((totalFileSize + i.files.item(idx).size) > 4000000) {
|
|
269
|
+
to_bin.push({ name: i.name, file: i.files.item(idx) });
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
270
272
|
totalFileSize += i.files.item(idx).size;
|
|
273
|
+
files.push({ name: i.name, file: i.files.item(idx) });
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
276
|
}
|
|
@@ -276,10 +279,7 @@ function extractFormMeta(form) {
|
|
|
276
279
|
}
|
|
277
280
|
}
|
|
278
281
|
}
|
|
279
|
-
|
|
280
|
-
throw new SkapiError('Total File size cannot exceed 4MB. Use skapi.uploadFiles() instead.', { code: 'INVALID_REQUEST' });
|
|
281
|
-
}
|
|
282
|
-
return { meta, files };
|
|
282
|
+
return { meta, files, to_bin };
|
|
283
283
|
}
|
|
284
284
|
return null;
|
|
285
285
|
}
|
package/js/utils/validator.js
CHANGED
|
@@ -85,26 +85,32 @@ function Url(url) {
|
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
87
|
let cu = c.trim();
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
90
|
-
|
|
88
|
+
if (cu[0] === '/' && baseUrl) {
|
|
89
|
+
if (baseUrl.slice(0, 5) === 'file:') {
|
|
90
|
+
throw new SkapiError(`"${c}" is an invalid url. Relative URL does not work on local file system. Use full URL string.`, { code: 'INVALID_PARAMETER' });
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
_url = new URL(cu);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
throw new SkapiError(`"${c}" is an invalid url.`, { code: 'INVALID_PARAMETER' });
|
|
92
|
+
cu = baseUrl + cu;
|
|
93
|
+
}
|
|
94
|
+
else if (cu[0] === '.' && baseUrl) {
|
|
95
|
+
if (baseUrl.slice(0, 5) === 'file:') {
|
|
96
|
+
throw new SkapiError(`"${c}" is an invalid url. Relative URL does not work on local file system. Use full URL string.`, { code: 'INVALID_PARAMETER' });
|
|
101
97
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
url = url.substring(0, url.length - 1);
|
|
106
|
-
return url;
|
|
98
|
+
let curr_loc = window.location.href.split('?')[0];
|
|
99
|
+
if (curr_loc.slice(-1) !== '/') {
|
|
100
|
+
curr_loc += '/';
|
|
107
101
|
}
|
|
102
|
+
cu = curr_loc + cu.slice(1);
|
|
103
|
+
}
|
|
104
|
+
let _url;
|
|
105
|
+
try {
|
|
106
|
+
_url = new URL(cu);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
throw new SkapiError(`"${c}" is an invalid url.`, { code: 'INVALID_PARAMETER' });
|
|
110
|
+
}
|
|
111
|
+
if (_url.protocol) {
|
|
112
|
+
let url = _url.href;
|
|
113
|
+
return url;
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
116
|
}
|
|
@@ -122,13 +128,13 @@ function specialChars(string, p = 'parameter', allowPeriods = false, allowWhiteS
|
|
|
122
128
|
if (typeof s !== 'string') {
|
|
123
129
|
throw new SkapiError(`${p} should be type: <string | string[]>.`, { code: 'INVALID_PARAMETER' });
|
|
124
130
|
}
|
|
125
|
-
if (!allowWhiteSpace &&
|
|
131
|
+
if (!allowWhiteSpace && s.includes(' ')) {
|
|
126
132
|
throw new SkapiError(`${p} should not have whitespace.`, { code: 'INVALID_PARAMETER' });
|
|
127
133
|
}
|
|
128
|
-
if (!allowPeriods &&
|
|
134
|
+
if (!allowPeriods && s.includes('.')) {
|
|
129
135
|
throw new SkapiError(`${p} should not have periods.`, { code: 'INVALID_PARAMETER' });
|
|
130
136
|
}
|
|
131
|
-
if (/[
|
|
137
|
+
if (/[!@#$%&*()+\-={};':"\|,<>\/?~]/.test(s)) {
|
|
132
138
|
throw new SkapiError(`${p} should not have special characters.`, { code: 'INVALID_PARAMETER' });
|
|
133
139
|
}
|
|
134
140
|
};
|