aio-login 9.0.0 → 10.0.0
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/index.css +1 -0
- package/index.d.ts +23 -15
- package/index.js +134 -105
- package/package.json +1 -1
package/index.css
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC, ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { I_validateType, I_formField, AITYPE } from "aio-input";
|
|
3
3
|
import './index.css';
|
|
4
4
|
type I_loginMode = 'userpass' | 'register' | 'otpcode' | 'otpnumber';
|
|
5
5
|
export type I_login_key = 'registerButton' | 'userpassButton' | 'otpnumberButton' | 'otpcodeButton' | 'registerTitle' | 'userpassTitle' | 'otpcodeTitle' | 'otpnumberTitle' | 'switchuserpass' | 'switchregister' | 'switchotpnumber' | 'repasswordMatch' | 'usernameRequired' | 'passwordRequired' | 'repasswordRequired' | 'otpnumberRequired' | 'otpcodeLength' | 'registerError' | 'userpassError' | 'otpcodeError' | 'otpnumberError' | 'username' | 'password' | 'repassword' | 'otpnumber' | 'otpcode';
|
|
@@ -19,9 +19,6 @@ type I_login_model<T> = {
|
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
-
type I_registerInputs = {
|
|
23
|
-
[field: string]: I_formInput;
|
|
24
|
-
};
|
|
25
22
|
type I_AILogin<T> = {
|
|
26
23
|
app: FC<{
|
|
27
24
|
user: T;
|
|
@@ -45,50 +42,61 @@ type I_AILogin<T> = {
|
|
|
45
42
|
html: ReactNode;
|
|
46
43
|
time: number;
|
|
47
44
|
};
|
|
48
|
-
validate?: (p: {
|
|
49
|
-
field: string;
|
|
50
|
-
data: I_login_model<T>;
|
|
51
|
-
value: any;
|
|
52
|
-
input: I_formInput;
|
|
53
|
-
}) => string | undefined;
|
|
54
45
|
otpnumber?: {
|
|
55
46
|
path: string;
|
|
56
47
|
method: 'post' | 'get';
|
|
57
|
-
body?: (
|
|
48
|
+
body?: (otpnumber: string) => any;
|
|
58
49
|
onSuccess: (response: any) => Promise<{
|
|
59
50
|
message?: string;
|
|
60
51
|
}>;
|
|
52
|
+
validate?: (number: string) => string | undefined;
|
|
61
53
|
};
|
|
62
54
|
otpcode?: {
|
|
63
55
|
length: number;
|
|
64
56
|
method: 'post' | 'get';
|
|
65
|
-
body?: (
|
|
57
|
+
body?: (otpcode: string) => any;
|
|
66
58
|
path: string;
|
|
67
59
|
onSuccess: (response: any) => Promise<{
|
|
68
60
|
user: T;
|
|
69
61
|
token: string;
|
|
70
62
|
message?: string;
|
|
71
63
|
}>;
|
|
64
|
+
validate?: (code: string) => string | undefined;
|
|
72
65
|
};
|
|
73
66
|
userpass?: {
|
|
74
67
|
path: string;
|
|
75
68
|
method: 'post' | 'get';
|
|
76
|
-
body?: (data: I_login_model<T>) => any;
|
|
69
|
+
body?: (data: I_login_model<T>["userpass"]) => any;
|
|
77
70
|
onSuccess: (response: any) => Promise<{
|
|
78
71
|
user: T;
|
|
79
72
|
token: string;
|
|
80
73
|
message?: string;
|
|
81
74
|
}>;
|
|
75
|
+
validate?: (p: {
|
|
76
|
+
field: 'username' | 'password';
|
|
77
|
+
value: string;
|
|
78
|
+
data: I_login_model<T>["userpass"];
|
|
79
|
+
}) => string | undefined;
|
|
82
80
|
};
|
|
83
81
|
register?: {
|
|
84
|
-
inputs?: (model: I_login_model<T>) =>
|
|
82
|
+
inputs?: (model: I_login_model<T>["register"]) => (AITYPE & {
|
|
83
|
+
label: string;
|
|
84
|
+
required?: boolean;
|
|
85
|
+
validateType?: I_validateType;
|
|
86
|
+
field: I_formField<T>;
|
|
87
|
+
})[];
|
|
85
88
|
path: string;
|
|
86
89
|
method: 'post' | 'get';
|
|
87
|
-
body?: (data: I_login_model<T>) => any;
|
|
90
|
+
body?: (data: I_login_model<T>["register"]) => any;
|
|
88
91
|
onSuccess: (response: any) => Promise<{
|
|
89
92
|
message?: string;
|
|
90
93
|
}>;
|
|
91
94
|
defaultData?: any;
|
|
95
|
+
validate?: (p: {
|
|
96
|
+
data: I_login_model<T>["register"];
|
|
97
|
+
field: string;
|
|
98
|
+
value: any;
|
|
99
|
+
}) => string | undefined;
|
|
92
100
|
};
|
|
93
101
|
getStatus?: (response: any) => number;
|
|
94
102
|
getMessage?: (response: any) => string;
|
package/index.js
CHANGED
|
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { useEffect, useState } from "react";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
import { useEffect, useRef, useState } from "react";
|
|
12
12
|
import { useForm } from "aio-input";
|
|
13
13
|
import { AddToAttrs, FixUrl, Storage } from "aio-utils";
|
|
14
14
|
import { Loading, Alert } from "aio-popup";
|
|
@@ -25,13 +25,15 @@ export function AIOLogin_updateCatchedUser(loginId, newUser) {
|
|
|
25
25
|
return storage.save('data', newStoredData);
|
|
26
26
|
}
|
|
27
27
|
const useLoading = (rootProps) => {
|
|
28
|
-
const { register, translate = () => { }, fa,
|
|
28
|
+
const { register, translate = () => { }, fa, userpass, splash, otpnumber, otpcode } = rootProps;
|
|
29
29
|
const [storage] = useState(new Storage('ai-login' + rootProps.id));
|
|
30
30
|
const [loading] = useState(new Loading());
|
|
31
31
|
const [splashing, setSplashing] = useState(!!rootProps.splash);
|
|
32
32
|
const [data, setData] = useState();
|
|
33
33
|
const [checkingToken, setCheckingToken] = useState();
|
|
34
34
|
const [mode, setMode] = useState(getMode);
|
|
35
|
+
const modeRef = useRef(mode);
|
|
36
|
+
modeRef.current = mode;
|
|
35
37
|
function getMode(mode) {
|
|
36
38
|
let key = 'userpass';
|
|
37
39
|
if (mode) {
|
|
@@ -56,72 +58,121 @@ const useLoading = (rootProps) => {
|
|
|
56
58
|
title: _jsx("div", { className: "ai-login-title", children: trans(key + 'Title') })
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
|
-
const
|
|
60
|
-
initData:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
return inputs;
|
|
80
|
-
},
|
|
81
|
-
validate: ({ field, data, value, input }) => {
|
|
82
|
-
if (field === 'otpcode') {
|
|
83
|
-
if ((value || '').length !== ((otpcode === null || otpcode === void 0 ? void 0 : otpcode.length) || 4)) {
|
|
84
|
-
return trans('otpcodeLength');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (!value) {
|
|
88
|
-
if (field === 'otpnumber') {
|
|
89
|
-
return trans('otpnumberRequired');
|
|
90
|
-
}
|
|
91
|
-
if (field === 'userpass.username') {
|
|
92
|
-
return trans('usernameRequired');
|
|
93
|
-
}
|
|
94
|
-
if (field === 'userpass.password') {
|
|
95
|
-
return trans('passwordRequired');
|
|
96
|
-
}
|
|
97
|
-
if (field === 'register.username') {
|
|
98
|
-
return trans('usernameRequired');
|
|
99
|
-
}
|
|
100
|
-
if (field === 'register.password') {
|
|
101
|
-
return trans('passwordRequired');
|
|
102
|
-
}
|
|
103
|
-
if (field === 'register.repassword') {
|
|
104
|
-
return trans('repasswordRequired');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (field === 'register.repassword' && data.register.password !== value) {
|
|
108
|
-
return trans('repasswordMatch');
|
|
109
|
-
}
|
|
110
|
-
return validate({ field, data, value, input });
|
|
61
|
+
const userpassHook = useForm({
|
|
62
|
+
initData: getModel().userpass,
|
|
63
|
+
getLayout: (context) => {
|
|
64
|
+
const { validate = () => { return undefined; } } = userpass || {};
|
|
65
|
+
return getLayout({
|
|
66
|
+
scroll: true,
|
|
67
|
+
v: [
|
|
68
|
+
{
|
|
69
|
+
input: {
|
|
70
|
+
field: 'username', type: 'text', label: trans('username'),
|
|
71
|
+
validate: ({ field, value, data }) => validate({ data, field: field, value })
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
input: {
|
|
76
|
+
field: 'password', type: 'password', preview: true, label: trans('password'), validate: ({ field, value, data }) => validate({ data, field: field, value })
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}, context);
|
|
111
81
|
},
|
|
112
|
-
onSubmit: (data) =>
|
|
113
|
-
|
|
82
|
+
onSubmit: (data) => onSubmit(data)
|
|
83
|
+
});
|
|
84
|
+
// const otpnumberHook = useForm<{otpnumber:string}>({
|
|
85
|
+
// initData: {otpnumber:''},
|
|
86
|
+
// getLayout: (context) => {
|
|
87
|
+
// const { validate = () => { return undefined } } = otpnumber || {}
|
|
88
|
+
// const {title,submitText} = modeRef.current
|
|
89
|
+
// return getLayout({
|
|
90
|
+
// attrs: { className: "ai-login-form" },
|
|
91
|
+
// v: [
|
|
92
|
+
// { html:title },
|
|
93
|
+
// {
|
|
94
|
+
// scroll: true,
|
|
95
|
+
// v: [
|
|
96
|
+
// {
|
|
97
|
+
// input: { field:'otpnumber',type: 'text', maxLength: 11, filter: ['number'], label: trans('otpnumber'),validate:({value})=>validate(value) }
|
|
98
|
+
// }
|
|
99
|
+
// ]
|
|
100
|
+
// },
|
|
101
|
+
// { html: <div style={{ height: 24 }}></div>, size: 24, },
|
|
102
|
+
// { html: context.renderSubmitButton(submitText,{ className: 'ai-login-submit' })},
|
|
103
|
+
// { html: renderModes() }
|
|
104
|
+
// ]
|
|
105
|
+
// },context)
|
|
106
|
+
// },
|
|
107
|
+
// onSubmit: (data)=>onSubmit<string>(data.otpnumber)
|
|
108
|
+
// })
|
|
109
|
+
// const otpcodeHook = useForm<{otpcode:string}>({
|
|
110
|
+
// initData: {otpcode:''},
|
|
111
|
+
// getLayout: (context) => {
|
|
112
|
+
// const { validate = () => { return undefined } } = otpcode || {}
|
|
113
|
+
// return getLayout({
|
|
114
|
+
// scroll: true,
|
|
115
|
+
// v: [
|
|
116
|
+
// {
|
|
117
|
+
// input: { field:'otpcode',type: 'text', maxLength: otpcode?.length || 4, filter: ['number'], label: trans('otpcode'),validate:({value})=>validate(value) }
|
|
118
|
+
// }
|
|
119
|
+
// ]
|
|
120
|
+
// },context)
|
|
121
|
+
// },
|
|
122
|
+
// onSubmit: (data)=>onSubmit<string>(data.otpcode)
|
|
123
|
+
// })
|
|
124
|
+
// const registerHook = useForm<I_login_model<T>["register"]>({
|
|
125
|
+
// initData: getModel().register,
|
|
126
|
+
// getLayout: (context) => {
|
|
127
|
+
// const { inputs = () => [],validate = ()=>{return undefined} } = register || {}
|
|
128
|
+
// return getLayout<I_login_model<T>["register"]>({
|
|
129
|
+
// scroll: true,
|
|
130
|
+
// v: [
|
|
131
|
+
// { input: { field: 'username', type: 'text', label: trans('username') } },
|
|
132
|
+
// { input: { field: 'password', type: 'password', preview: true, label: trans('password') } },
|
|
133
|
+
// { input: { field: 'repassword', type: 'password', preview: true, label: trans('repassword') } },
|
|
134
|
+
// {
|
|
135
|
+
// v: inputs(context.getData()).map((input) => {
|
|
136
|
+
// return { input:{...input,field:`properties.${input.field}`,validate:({field,value,data})=>validate({data,field,value})} }
|
|
137
|
+
// })
|
|
138
|
+
// }
|
|
139
|
+
// ]
|
|
140
|
+
// },context)
|
|
141
|
+
// },
|
|
142
|
+
// onSubmit: (data)=>onSubmit<I_login_model<T>["register"]>(data)
|
|
143
|
+
// })
|
|
144
|
+
function onSubmit(data) {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
const { path, method, body = () => { } } = rootProps[mode.key];
|
|
114
147
|
const { base_url } = rootProps;
|
|
115
148
|
const url = FixUrl(base_url, path);
|
|
116
149
|
loading.show('login0');
|
|
117
|
-
loading.hide('login0');
|
|
118
150
|
axios[method](url, body(data)).then(success).catch(response => {
|
|
119
|
-
const
|
|
120
|
-
|
|
151
|
+
const text = getMessage(response, mode.key);
|
|
152
|
+
loading.hide('login0');
|
|
153
|
+
Alert({ type: 'error', title: trans(`${mode.key}Error`), text });
|
|
121
154
|
});
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
function
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function getLayout(node, context) {
|
|
158
|
+
const { title, submitText } = modeRef.current;
|
|
159
|
+
return {
|
|
160
|
+
attrs: { className: "ai-login-form" },
|
|
161
|
+
v: [
|
|
162
|
+
{ html: title },
|
|
163
|
+
node,
|
|
164
|
+
{ html: _jsx("div", { style: { height: 24 } }), size: 24, },
|
|
165
|
+
{ html: context.renderSubmitButton(submitText, { className: 'ai-login-submit' }) },
|
|
166
|
+
{ html: renderModes() }
|
|
167
|
+
]
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function changeMode(mode) {
|
|
171
|
+
if (mode === 'userpass') {
|
|
172
|
+
userpassHook.changeData(getModel().userpass);
|
|
173
|
+
}
|
|
174
|
+
//else if(mode === 'register'){registerHook.changeData(getModel().register)}
|
|
175
|
+
}
|
|
125
176
|
function success_1(response, mode) {
|
|
126
177
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
178
|
if (!rootProps[mode]) {
|
|
@@ -133,7 +184,7 @@ const useLoading = (rootProps) => {
|
|
|
133
184
|
loading.hide('login0');
|
|
134
185
|
if (typeof res !== 'object' || !res.user || typeof res.token !== 'string') {
|
|
135
186
|
const message = `onSuccess of props.${mode}.${mode === 'userpass' ? 'api' : 'codeApi'} should returns {user:any,token:string}`;
|
|
136
|
-
Alert({ type: 'error',
|
|
187
|
+
Alert({ type: 'error', title: trans(`${mode}Error`), text: message });
|
|
137
188
|
}
|
|
138
189
|
else {
|
|
139
190
|
if (res.message) {
|
|
@@ -167,6 +218,7 @@ const useLoading = (rootProps) => {
|
|
|
167
218
|
}
|
|
168
219
|
function success(response) {
|
|
169
220
|
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
loading.hide('login0');
|
|
170
222
|
if (mode.key === 'userpass' || mode.key === 'otpcode') {
|
|
171
223
|
success_1(response, mode.key);
|
|
172
224
|
}
|
|
@@ -176,9 +228,8 @@ const useLoading = (rootProps) => {
|
|
|
176
228
|
});
|
|
177
229
|
}
|
|
178
230
|
const getStatus = (error, name) => {
|
|
179
|
-
let
|
|
231
|
+
let title = `${name} unknown status.`, text = 'please set getStatus props in useLogin for extracting status';
|
|
180
232
|
if (error.response) {
|
|
181
|
-
const data = error.response.data;
|
|
182
233
|
let status = error.response.status;
|
|
183
234
|
if (typeof status !== 'number') {
|
|
184
235
|
const { getStatus = () => { } } = rootProps;
|
|
@@ -188,10 +239,10 @@ const useLoading = (rootProps) => {
|
|
|
188
239
|
}
|
|
189
240
|
}
|
|
190
241
|
}
|
|
191
|
-
Alert({ type: 'error',
|
|
242
|
+
Alert({ type: 'error', title, text });
|
|
192
243
|
};
|
|
193
244
|
const getMessage = (error, name) => {
|
|
194
|
-
let
|
|
245
|
+
let title = `${name} unknown message.`, text = 'please set getMessage props in useLogin for extracting message';
|
|
195
246
|
if (error.response) {
|
|
196
247
|
const data = error.response.data;
|
|
197
248
|
if (typeof data === 'string') {
|
|
@@ -217,7 +268,7 @@ const useLoading = (rootProps) => {
|
|
|
217
268
|
else if (typeof error.message === 'string') {
|
|
218
269
|
return error.message;
|
|
219
270
|
}
|
|
220
|
-
Alert({
|
|
271
|
+
Alert({ title, text, type: 'error' });
|
|
221
272
|
return 'unkown message';
|
|
222
273
|
};
|
|
223
274
|
const checkTokenCatch = (error) => {
|
|
@@ -226,11 +277,11 @@ const useLoading = (rootProps) => {
|
|
|
226
277
|
logout();
|
|
227
278
|
}
|
|
228
279
|
const message = getMessage(error, 'checking token');
|
|
229
|
-
let
|
|
280
|
+
let title = 'error in checking token';
|
|
230
281
|
if (rootProps.fa) {
|
|
231
|
-
|
|
282
|
+
title = 'خطا در بررسی توکن';
|
|
232
283
|
}
|
|
233
|
-
Alert({ type: 'error',
|
|
284
|
+
Alert({ type: 'error', title, text: message });
|
|
234
285
|
};
|
|
235
286
|
const checkTokenThen = (response, user, token) => {
|
|
236
287
|
const { checkToken } = rootProps;
|
|
@@ -244,7 +295,7 @@ const useLoading = (rootProps) => {
|
|
|
244
295
|
logout();
|
|
245
296
|
}
|
|
246
297
|
else {
|
|
247
|
-
Alert({ type: 'error',
|
|
298
|
+
Alert({ type: 'error', title: 'check token error', text: 'checkToken.getResult should returns boolean' });
|
|
248
299
|
}
|
|
249
300
|
};
|
|
250
301
|
function CheckToken() {
|
|
@@ -327,27 +378,8 @@ const useLoading = (rootProps) => {
|
|
|
327
378
|
}
|
|
328
379
|
return model;
|
|
329
380
|
}
|
|
330
|
-
const getFormNode = () => {
|
|
331
|
-
let registerInputs = {};
|
|
332
|
-
if (register && register.inputs) {
|
|
333
|
-
registerInputs = register.inputs(formHook.data);
|
|
334
|
-
}
|
|
335
|
-
const registerFields = Object.keys(registerInputs);
|
|
336
|
-
return {
|
|
337
|
-
scroll: true,
|
|
338
|
-
v: [
|
|
339
|
-
{ input: 'userpass.username', show: mode.key === 'userpass' },
|
|
340
|
-
{ input: 'userpass.password', show: mode.key === 'userpass' },
|
|
341
|
-
{ input: 'register.username', show: mode.key === 'register' },
|
|
342
|
-
{ input: 'register.password', show: mode.key === 'register' },
|
|
343
|
-
{ input: 'register.repassword', show: mode.key === 'register' },
|
|
344
|
-
{ input: 'otpnumber', show: mode.key === 'otpnumber' },
|
|
345
|
-
{ input: 'otpcode', show: mode.key === 'otpcode' },
|
|
346
|
-
{ v: registerFields.map((field) => ({ input: `register.properties.${field}`, show: mode.key === 'register' })) }
|
|
347
|
-
]
|
|
348
|
-
};
|
|
349
|
-
};
|
|
350
381
|
function renderMode(modeKey) {
|
|
382
|
+
const mode = modeRef.current;
|
|
351
383
|
if (mode.key === modeKey) {
|
|
352
384
|
return null;
|
|
353
385
|
}
|
|
@@ -357,17 +389,14 @@ const useLoading = (rootProps) => {
|
|
|
357
389
|
return (_jsxs("div", { className: "ai-login-modes", children: [userpass && renderMode('userpass'), register && renderMode('register'), otpnumber && renderMode('otpnumber')] }));
|
|
358
390
|
}
|
|
359
391
|
function renderLoginBox() {
|
|
360
|
-
const {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
{ html: renderModes() }
|
|
369
|
-
]
|
|
370
|
-
});
|
|
392
|
+
const { key } = mode;
|
|
393
|
+
if (key === 'userpass') {
|
|
394
|
+
return _jsx(_Fragment, { children: userpassHook.renderLayout });
|
|
395
|
+
}
|
|
396
|
+
//if(key === 'register'){return <>{registerHook.renderLayout}</>}
|
|
397
|
+
//if(key === 'otpnumber'){return <>{otpnumberHook.renderLayout}</>}
|
|
398
|
+
//if(key === 'otpcode'){return <>{otpcodeHook.renderLayout}</>}
|
|
399
|
+
return null;
|
|
371
400
|
}
|
|
372
401
|
const bf_layout = (type) => {
|
|
373
402
|
const fn = rootProps[type];
|
|
@@ -404,7 +433,7 @@ const useLoading = (rootProps) => {
|
|
|
404
433
|
splashing, loading, checkingToken,
|
|
405
434
|
data, setData,
|
|
406
435
|
getMessage, trans,
|
|
407
|
-
getModel,
|
|
436
|
+
getModel,
|
|
408
437
|
mode, getMode, setMode, changeMode,
|
|
409
438
|
renderApp, renderLoginBox, renderLoginPage
|
|
410
439
|
};
|