tale-js-sdk 0.1.2 → 0.1.4
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/dist/acl/index.d.ts +170 -0
- package/dist/acl/index.js +747 -0
- package/dist/acl/types.d.ts +208 -0
- package/dist/acl/types.js +1 -0
- package/dist/auth/index.d.ts +2 -134
- package/dist/auth/index.js +120 -96
- package/dist/auth/types.d.ts +122 -0
- package/dist/auth/types.js +1 -0
- package/dist/common/types.d.ts +82 -0
- package/dist/common/types.js +2 -0
- package/dist/errors.js +18 -18
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/rbac/acl.d.ts +152 -0
- package/dist/rbac/acl.js +723 -0
- package/dist/rbac/index.d.ts +2 -0
- package/dist/rbac/index.js +2 -0
- package/dist/rbac/rbac.d.ts +198 -0
- package/dist/rbac/rbac.js +984 -0
- package/dist/rbac/types.d.ts +356 -0
- package/dist/rbac/types.js +1 -0
- package/dist/rbac/user-group.d.ts +122 -0
- package/dist/rbac/user-group.js +570 -0
- package/dist/status.js +3 -3
- package/dist/token.d.ts +1 -1
- package/dist/token.js +5 -4
- package/dist/user/index.d.ts +165 -142
- package/dist/user/index.js +511 -59
- package/dist/user/types.d.ts +149 -0
- package/dist/user/types.js +1 -0
- package/dist/user-group/index.d.ts +230 -0
- package/dist/user-group/index.js +560 -0
- package/dist/user-group/types.d.ts +64 -0
- package/dist/user-group/types.js +1 -0
- package/package.json +4 -3
- package/dist/auth.d.ts +0 -271
- package/dist/auth.js +0 -461
- package/dist/client.d.ts +0 -20
- package/dist/client.js +0 -62
- package/dist/info.d.ts +0 -9
- package/dist/info.js +0 -18
- package/dist/package.json +0 -36
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -1
- package/dist/src/info.d.ts +0 -6
- package/dist/src/info.js +0 -4
- package/dist/user.d.ts +0 -242
- package/dist/user.js +0 -331
package/dist/auth/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getAppToken } from
|
|
2
|
-
import { ApiError, ConfigurationError, NetworkError } from
|
|
1
|
+
import { getAppToken } from "../token.js";
|
|
2
|
+
import { ApiError, ConfigurationError, NetworkError } from "../errors.js";
|
|
3
3
|
/**
|
|
4
4
|
* Authenticates a user with username and password.
|
|
5
5
|
*
|
|
@@ -32,24 +32,24 @@ import { ApiError, ConfigurationError, NetworkError } from '../errors.js';
|
|
|
32
32
|
*/
|
|
33
33
|
export async function login(credentials, options) {
|
|
34
34
|
// Validate required fields
|
|
35
|
-
if (!credentials.username || credentials.username.trim() ===
|
|
36
|
-
throw new ApiError(
|
|
35
|
+
if (!credentials.username || credentials.username.trim() === "") {
|
|
36
|
+
throw new ApiError("username is required", 400, "9400");
|
|
37
37
|
}
|
|
38
|
-
if (!credentials.password || credentials.password.trim() ===
|
|
39
|
-
throw new ApiError(
|
|
38
|
+
if (!credentials.password || credentials.password.trim() === "") {
|
|
39
|
+
throw new ApiError("password is required", 400, "9400");
|
|
40
40
|
}
|
|
41
41
|
// Determine base URL
|
|
42
42
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
43
43
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
44
44
|
if (!base) {
|
|
45
|
-
throw new ConfigurationError(
|
|
45
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
46
46
|
}
|
|
47
47
|
// Get app key from environment variable
|
|
48
48
|
const appKey = env?.TALE_APP_KEY;
|
|
49
49
|
if (!appKey) {
|
|
50
|
-
throw new ConfigurationError(
|
|
50
|
+
throw new ConfigurationError("Missing required environment variable: TALE_APP_KEY");
|
|
51
51
|
}
|
|
52
|
-
const url = String(base).replace(/\/+$/,
|
|
52
|
+
const url = String(base).replace(/\/+$/, "") + "/auth/v1/login/username-password";
|
|
53
53
|
// Build request body
|
|
54
54
|
const requestBody = {
|
|
55
55
|
username: credentials.username.trim(),
|
|
@@ -57,20 +57,20 @@ export async function login(credentials, options) {
|
|
|
57
57
|
app_key: appKey,
|
|
58
58
|
device_name: options?.device_name,
|
|
59
59
|
device_fingerprint: options?.device_fingerprint,
|
|
60
|
-
scope: options?.scope ||
|
|
60
|
+
scope: options?.scope || "",
|
|
61
61
|
};
|
|
62
62
|
let response;
|
|
63
63
|
try {
|
|
64
64
|
response = await globalThis.fetch(url, {
|
|
65
|
-
method:
|
|
65
|
+
method: "POST",
|
|
66
66
|
headers: {
|
|
67
|
-
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
68
|
},
|
|
69
69
|
body: JSON.stringify(requestBody),
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
catch (error) {
|
|
73
|
-
throw new NetworkError(`Failed to authenticate user: ${error instanceof Error ? error.message :
|
|
73
|
+
throw new NetworkError(`Failed to authenticate user: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
74
74
|
}
|
|
75
75
|
let json;
|
|
76
76
|
try {
|
|
@@ -78,31 +78,37 @@ export async function login(credentials, options) {
|
|
|
78
78
|
json = responseJson;
|
|
79
79
|
}
|
|
80
80
|
catch (error) {
|
|
81
|
-
throw new ApiError(`Failed to parse login response: ${error instanceof Error ? error.message :
|
|
81
|
+
throw new ApiError(`Failed to parse login response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
82
82
|
}
|
|
83
83
|
// Handle authentication errors based on response status
|
|
84
84
|
if (response.status === 400) {
|
|
85
|
-
const errorMsg = typeof json ===
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const errorMsg = typeof json === "object" &&
|
|
86
|
+
json !== null &&
|
|
87
|
+
("message" in json || "msg" in json)
|
|
88
|
+
? String(json.message || json.msg)
|
|
89
|
+
: "Authentication failed";
|
|
90
|
+
throw new ApiError(errorMsg, response.status, "9400");
|
|
88
91
|
}
|
|
89
92
|
if (response.status === 403) {
|
|
90
|
-
throw new ApiError(
|
|
93
|
+
throw new ApiError("Account is frozen or access forbidden", response.status, "9403");
|
|
91
94
|
}
|
|
92
95
|
if (response.status === 401) {
|
|
93
|
-
throw new ApiError(
|
|
96
|
+
throw new ApiError("Invalid app_key or authentication failed", response.status, "9401");
|
|
94
97
|
}
|
|
95
98
|
if (!response.ok) {
|
|
96
|
-
const errorMsg = typeof json ===
|
|
97
|
-
|
|
99
|
+
const errorMsg = typeof json === "object" &&
|
|
100
|
+
json !== null &&
|
|
101
|
+
("message" in json || "msg" in json)
|
|
102
|
+
? String(json.message || json.msg)
|
|
103
|
+
: "Authentication failed";
|
|
98
104
|
throw new ApiError(errorMsg, response.status);
|
|
99
105
|
}
|
|
100
106
|
// Handle response data structure - check if data is wrapped in a 'data' field
|
|
101
107
|
const responseData = json.data || json;
|
|
102
108
|
// Validate response structure
|
|
103
109
|
if (!responseData || !responseData.user || !responseData.token) {
|
|
104
|
-
console.error(
|
|
105
|
-
throw new ApiError(
|
|
110
|
+
console.error("Invalid response structure:", { json, responseData });
|
|
111
|
+
throw new ApiError("Invalid login response: missing required data", response.status);
|
|
106
112
|
}
|
|
107
113
|
// Build standard response structure
|
|
108
114
|
const loginResponse = {
|
|
@@ -112,7 +118,7 @@ export async function login(credentials, options) {
|
|
|
112
118
|
user_roles: responseData.user_roles || [],
|
|
113
119
|
user_privileges: responseData.user_privileges || [],
|
|
114
120
|
user_groups: responseData.user_groups || [],
|
|
115
|
-
user_login_methods: responseData.user_login_methods || []
|
|
121
|
+
user_login_methods: responseData.user_login_methods || [],
|
|
116
122
|
};
|
|
117
123
|
return loginResponse;
|
|
118
124
|
}
|
|
@@ -140,31 +146,31 @@ export async function login(credentials, options) {
|
|
|
140
146
|
*/
|
|
141
147
|
export async function validateToken(token, options) {
|
|
142
148
|
// Validate required fields
|
|
143
|
-
if (!token || token.trim() ===
|
|
144
|
-
throw new ApiError(
|
|
149
|
+
if (!token || token.trim() === "") {
|
|
150
|
+
throw new ApiError("token is required", 400, "9400");
|
|
145
151
|
}
|
|
146
152
|
// Determine base URL
|
|
147
153
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
148
154
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
149
155
|
if (!base) {
|
|
150
|
-
throw new ConfigurationError(
|
|
156
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
151
157
|
}
|
|
152
|
-
const url = new URL(String(base).replace(/\/+$/,
|
|
158
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/auth/v1/assert_token");
|
|
153
159
|
if (options?.scope) {
|
|
154
|
-
url.searchParams.append(
|
|
160
|
+
url.searchParams.append("scope", options.scope);
|
|
155
161
|
}
|
|
156
162
|
let response;
|
|
157
163
|
try {
|
|
158
164
|
response = await globalThis.fetch(url.toString(), {
|
|
159
|
-
method:
|
|
165
|
+
method: "GET",
|
|
160
166
|
headers: {
|
|
161
|
-
|
|
162
|
-
|
|
167
|
+
"Content-Type": "application/json",
|
|
168
|
+
"x-t-token": token.trim(),
|
|
163
169
|
},
|
|
164
170
|
});
|
|
165
171
|
}
|
|
166
172
|
catch (error) {
|
|
167
|
-
throw new NetworkError(`Failed to validate token: ${error instanceof Error ? error.message :
|
|
173
|
+
throw new NetworkError(`Failed to validate token: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
168
174
|
}
|
|
169
175
|
// Token is valid if we get a 200 response
|
|
170
176
|
return response.ok;
|
|
@@ -194,31 +200,31 @@ export async function validateToken(token, options) {
|
|
|
194
200
|
*/
|
|
195
201
|
export async function loginWithSms(phone, options) {
|
|
196
202
|
// Validate required fields
|
|
197
|
-
if (!phone || phone.trim() ===
|
|
198
|
-
throw new ApiError(
|
|
203
|
+
if (!phone || phone.trim() === "") {
|
|
204
|
+
throw new ApiError("phone number is required", 400, "9400");
|
|
199
205
|
}
|
|
200
206
|
// Determine base URL from environment variables
|
|
201
207
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
202
208
|
const base = env?.TALE_BASE_URL;
|
|
203
209
|
if (!base) {
|
|
204
|
-
throw new ConfigurationError(
|
|
210
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
205
211
|
}
|
|
206
212
|
// Use provided app token or get one from token service
|
|
207
|
-
const authToken = options?.appToken ?? await getAppToken();
|
|
208
|
-
const url = new URL(String(base).replace(/\/+$/,
|
|
209
|
-
url.searchParams.append(
|
|
213
|
+
const authToken = options?.appToken ?? (await getAppToken());
|
|
214
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/auth/v1/sms/login_or_register");
|
|
215
|
+
url.searchParams.append("phone", phone.trim());
|
|
210
216
|
let response;
|
|
211
217
|
try {
|
|
212
218
|
response = await globalThis.fetch(url.toString(), {
|
|
213
|
-
method:
|
|
219
|
+
method: "GET",
|
|
214
220
|
headers: {
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
"x-t-token": authToken,
|
|
222
|
+
"Content-Type": "application/json",
|
|
217
223
|
},
|
|
218
224
|
});
|
|
219
225
|
}
|
|
220
226
|
catch (error) {
|
|
221
|
-
throw new NetworkError(`Failed to send SMS verification: ${error instanceof Error ? error.message :
|
|
227
|
+
throw new NetworkError(`Failed to send SMS verification: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
222
228
|
}
|
|
223
229
|
let json;
|
|
224
230
|
try {
|
|
@@ -226,34 +232,40 @@ export async function loginWithSms(phone, options) {
|
|
|
226
232
|
json = responseJson;
|
|
227
233
|
}
|
|
228
234
|
catch (error) {
|
|
229
|
-
throw new ApiError(`Failed to parse SMS response: ${error instanceof Error ? error.message :
|
|
235
|
+
throw new ApiError(`Failed to parse SMS response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
230
236
|
}
|
|
231
237
|
// Handle API errors
|
|
232
238
|
if (response.status === 400) {
|
|
233
|
-
const errorMsg = typeof json ===
|
|
234
|
-
|
|
235
|
-
|
|
239
|
+
const errorMsg = typeof json === "object" &&
|
|
240
|
+
json !== null &&
|
|
241
|
+
("message" in json || "msg" in json)
|
|
242
|
+
? String(json.message || json.msg)
|
|
243
|
+
: "Invalid phone number format";
|
|
244
|
+
throw new ApiError(errorMsg, response.status, "9400");
|
|
236
245
|
}
|
|
237
246
|
if (response.status === 429) {
|
|
238
|
-
throw new ApiError(
|
|
247
|
+
throw new ApiError("SMS sending rate limit exceeded", response.status, "9705");
|
|
239
248
|
}
|
|
240
249
|
if (!response.ok) {
|
|
241
|
-
const errorMsg = typeof json ===
|
|
242
|
-
|
|
250
|
+
const errorMsg = typeof json === "object" &&
|
|
251
|
+
json !== null &&
|
|
252
|
+
("message" in json || "msg" in json)
|
|
253
|
+
? String(json.message || json.msg)
|
|
254
|
+
: "SMS sending failed";
|
|
243
255
|
throw new ApiError(errorMsg, response.status);
|
|
244
256
|
}
|
|
245
257
|
// Handle response data structure - check if data is wrapped in a 'data' field
|
|
246
258
|
const responseData = json.data || json;
|
|
247
259
|
// Validate response structure
|
|
248
260
|
if (!responseData || !responseData.sms_id || !responseData.type) {
|
|
249
|
-
throw new ApiError(
|
|
261
|
+
throw new ApiError("Invalid SMS response: missing required data", response.status);
|
|
250
262
|
}
|
|
251
263
|
return {
|
|
252
264
|
app_key: responseData.app_key,
|
|
253
265
|
phone: responseData.phone,
|
|
254
266
|
type: responseData.type,
|
|
255
267
|
sms_id: responseData.sms_id,
|
|
256
|
-
expired_at: responseData.expired_at
|
|
268
|
+
expired_at: responseData.expired_at,
|
|
257
269
|
};
|
|
258
270
|
}
|
|
259
271
|
/**
|
|
@@ -285,39 +297,39 @@ export async function loginWithSms(phone, options) {
|
|
|
285
297
|
*/
|
|
286
298
|
export async function verifySmsCode(request, options) {
|
|
287
299
|
// Validate required fields
|
|
288
|
-
if (!request.sms_id || request.sms_id.trim() ===
|
|
289
|
-
throw new ApiError(
|
|
300
|
+
if (!request.sms_id || request.sms_id.trim() === "") {
|
|
301
|
+
throw new ApiError("sms_id is required", 400, "9400");
|
|
290
302
|
}
|
|
291
|
-
if (!request.sms_type || ![
|
|
292
|
-
throw new ApiError('sms_type must be "login" or "register"', 400,
|
|
303
|
+
if (!request.sms_type || !["login", "register"].includes(request.sms_type)) {
|
|
304
|
+
throw new ApiError('sms_type must be "login" or "register"', 400, "9400");
|
|
293
305
|
}
|
|
294
|
-
if (!request.verification_code || request.verification_code.trim() ===
|
|
295
|
-
throw new ApiError(
|
|
306
|
+
if (!request.verification_code || request.verification_code.trim() === "") {
|
|
307
|
+
throw new ApiError("verification_code is required", 400, "9400");
|
|
296
308
|
}
|
|
297
309
|
// Determine base URL
|
|
298
310
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
299
311
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
300
312
|
if (!base) {
|
|
301
|
-
throw new ConfigurationError(
|
|
313
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
302
314
|
}
|
|
303
315
|
// Use provided app token or get one from token service
|
|
304
|
-
const authToken = options?.appToken ?? await getAppToken(options);
|
|
305
|
-
const url = new URL(String(base).replace(/\/+$/,
|
|
306
|
-
url.searchParams.append(
|
|
307
|
-
url.searchParams.append(
|
|
308
|
-
url.searchParams.append(
|
|
316
|
+
const authToken = options?.appToken ?? (await getAppToken(options));
|
|
317
|
+
const url = new URL(String(base).replace(/\/+$/, "") + "/auth/v1/sms/verify");
|
|
318
|
+
url.searchParams.append("sms_id", request.sms_id.trim());
|
|
319
|
+
url.searchParams.append("sms_type", request.sms_type);
|
|
320
|
+
url.searchParams.append("verification_code", request.verification_code.trim());
|
|
309
321
|
let response;
|
|
310
322
|
try {
|
|
311
323
|
response = await globalThis.fetch(url.toString(), {
|
|
312
|
-
method:
|
|
324
|
+
method: "GET",
|
|
313
325
|
headers: {
|
|
314
|
-
|
|
315
|
-
|
|
326
|
+
"x-t-token": authToken,
|
|
327
|
+
"Content-Type": "application/json",
|
|
316
328
|
},
|
|
317
329
|
});
|
|
318
330
|
}
|
|
319
331
|
catch (error) {
|
|
320
|
-
throw new NetworkError(`Failed to verify SMS code: ${error instanceof Error ? error.message :
|
|
332
|
+
throw new NetworkError(`Failed to verify SMS code: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
321
333
|
}
|
|
322
334
|
let json;
|
|
323
335
|
try {
|
|
@@ -325,27 +337,33 @@ export async function verifySmsCode(request, options) {
|
|
|
325
337
|
json = responseJson;
|
|
326
338
|
}
|
|
327
339
|
catch (error) {
|
|
328
|
-
throw new ApiError(`Failed to parse SMS verification response: ${error instanceof Error ? error.message :
|
|
340
|
+
throw new ApiError(`Failed to parse SMS verification response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
329
341
|
}
|
|
330
342
|
// Handle verification errors
|
|
331
343
|
if (response.status === 400) {
|
|
332
|
-
const errorMsg = typeof json ===
|
|
333
|
-
|
|
334
|
-
|
|
344
|
+
const errorMsg = typeof json === "object" &&
|
|
345
|
+
json !== null &&
|
|
346
|
+
("message" in json || "msg" in json)
|
|
347
|
+
? String(json.message || json.msg)
|
|
348
|
+
: "SMS verification failed";
|
|
349
|
+
throw new ApiError(errorMsg, response.status, "9739");
|
|
335
350
|
}
|
|
336
351
|
if (response.status === 403) {
|
|
337
|
-
throw new ApiError(
|
|
352
|
+
throw new ApiError("Account is frozen or access forbidden", response.status, "9403");
|
|
338
353
|
}
|
|
339
354
|
if (!response.ok) {
|
|
340
|
-
const errorMsg = typeof json ===
|
|
341
|
-
|
|
355
|
+
const errorMsg = typeof json === "object" &&
|
|
356
|
+
json !== null &&
|
|
357
|
+
("message" in json || "msg" in json)
|
|
358
|
+
? String(json.message || json.msg)
|
|
359
|
+
: "SMS verification failed";
|
|
342
360
|
throw new ApiError(errorMsg, response.status);
|
|
343
361
|
}
|
|
344
362
|
// Handle response data structure - check if data is wrapped in a 'data' field
|
|
345
363
|
const responseData = json.data || json;
|
|
346
364
|
// Validate response structure
|
|
347
365
|
if (!responseData || !responseData.user || !responseData.token) {
|
|
348
|
-
throw new ApiError(
|
|
366
|
+
throw new ApiError("Invalid SMS verification response: missing required data", response.status);
|
|
349
367
|
}
|
|
350
368
|
// Build standard response structure
|
|
351
369
|
const smsLoginResponse = {
|
|
@@ -355,7 +373,7 @@ export async function verifySmsCode(request, options) {
|
|
|
355
373
|
user_roles: responseData.user_roles || [],
|
|
356
374
|
user_privileges: responseData.user_privileges || [],
|
|
357
375
|
user_groups: responseData.user_groups || [],
|
|
358
|
-
user_login_methods: responseData.user_login_methods || []
|
|
376
|
+
user_login_methods: responseData.user_login_methods || [],
|
|
359
377
|
};
|
|
360
378
|
return smsLoginResponse;
|
|
361
379
|
}
|
|
@@ -390,39 +408,39 @@ export async function verifySmsCode(request, options) {
|
|
|
390
408
|
*/
|
|
391
409
|
export async function registerWithSms(request, options) {
|
|
392
410
|
// Validate required fields for registration
|
|
393
|
-
if (request.sms_type !==
|
|
394
|
-
throw new ApiError('sms_type must be "register" for registration', 400,
|
|
411
|
+
if (request.sms_type !== "register") {
|
|
412
|
+
throw new ApiError('sms_type must be "register" for registration', 400, "9400");
|
|
395
413
|
}
|
|
396
414
|
// Determine base URL
|
|
397
415
|
const env = globalThis?.process?.env ?? import.meta?.env ?? undefined;
|
|
398
416
|
const base = options?.baseUrl ?? env?.TALE_BASE_URL ?? undefined;
|
|
399
417
|
if (!base) {
|
|
400
|
-
throw new ConfigurationError(
|
|
418
|
+
throw new ConfigurationError("Missing required environment variable: TALE_BASE_URL");
|
|
401
419
|
}
|
|
402
420
|
// Use provided app token or get one from token service
|
|
403
|
-
const authToken = options?.appToken ?? await getAppToken(options);
|
|
404
|
-
const url = String(base).replace(/\/+$/,
|
|
421
|
+
const authToken = options?.appToken ?? (await getAppToken(options));
|
|
422
|
+
const url = String(base).replace(/\/+$/, "") + "/auth/v1/sms/register/verify";
|
|
405
423
|
// Build request body
|
|
406
424
|
const requestBody = {
|
|
407
425
|
sms_id: request.sms_id.trim(),
|
|
408
426
|
sms_type: request.sms_type,
|
|
409
427
|
verification_code: request.verification_code.trim(),
|
|
410
428
|
username: request.username?.trim(),
|
|
411
|
-
password_encrypted: request.password_encrypted
|
|
429
|
+
password_encrypted: request.password_encrypted,
|
|
412
430
|
};
|
|
413
431
|
let response;
|
|
414
432
|
try {
|
|
415
433
|
response = await globalThis.fetch(url, {
|
|
416
|
-
method:
|
|
434
|
+
method: "POST",
|
|
417
435
|
headers: {
|
|
418
|
-
|
|
419
|
-
|
|
436
|
+
"x-t-token": authToken,
|
|
437
|
+
"Content-Type": "application/json",
|
|
420
438
|
},
|
|
421
439
|
body: JSON.stringify(requestBody),
|
|
422
440
|
});
|
|
423
441
|
}
|
|
424
442
|
catch (error) {
|
|
425
|
-
throw new NetworkError(`Failed to register with SMS: ${error instanceof Error ? error.message :
|
|
443
|
+
throw new NetworkError(`Failed to register with SMS: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
426
444
|
}
|
|
427
445
|
let json;
|
|
428
446
|
try {
|
|
@@ -430,27 +448,33 @@ export async function registerWithSms(request, options) {
|
|
|
430
448
|
json = responseJson;
|
|
431
449
|
}
|
|
432
450
|
catch (error) {
|
|
433
|
-
throw new ApiError(`Failed to parse registration response: ${error instanceof Error ? error.message :
|
|
451
|
+
throw new ApiError(`Failed to parse registration response: ${error instanceof Error ? error.message : "Invalid JSON"}`, response.status);
|
|
434
452
|
}
|
|
435
453
|
// Handle registration errors
|
|
436
454
|
if (response.status === 400) {
|
|
437
|
-
const errorMsg = typeof json ===
|
|
438
|
-
|
|
439
|
-
|
|
455
|
+
const errorMsg = typeof json === "object" &&
|
|
456
|
+
json !== null &&
|
|
457
|
+
("message" in json || "msg" in json)
|
|
458
|
+
? String(json.message || json.msg)
|
|
459
|
+
: "SMS registration failed";
|
|
460
|
+
throw new ApiError(errorMsg, response.status, "9739");
|
|
440
461
|
}
|
|
441
462
|
if (response.status === 403) {
|
|
442
|
-
throw new ApiError(
|
|
463
|
+
throw new ApiError("Account is frozen or access forbidden", response.status, "9403");
|
|
443
464
|
}
|
|
444
465
|
if (!response.ok) {
|
|
445
|
-
const errorMsg = typeof json ===
|
|
446
|
-
|
|
466
|
+
const errorMsg = typeof json === "object" &&
|
|
467
|
+
json !== null &&
|
|
468
|
+
("message" in json || "msg" in json)
|
|
469
|
+
? String(json.message || json.msg)
|
|
470
|
+
: "SMS registration failed";
|
|
447
471
|
throw new ApiError(errorMsg, response.status);
|
|
448
472
|
}
|
|
449
473
|
// Handle response data structure - check if data is wrapped in a 'data' field
|
|
450
474
|
const responseData = json.data || json;
|
|
451
475
|
// Validate response structure
|
|
452
476
|
if (!responseData || !responseData.user || !responseData.token) {
|
|
453
|
-
throw new ApiError(
|
|
477
|
+
throw new ApiError("Invalid registration response: missing required data", response.status);
|
|
454
478
|
}
|
|
455
479
|
// Build standard response structure
|
|
456
480
|
const registrationResponse = {
|
|
@@ -460,7 +484,7 @@ export async function registerWithSms(request, options) {
|
|
|
460
484
|
user_roles: responseData.user_roles || [],
|
|
461
485
|
user_privileges: responseData.user_privileges || [],
|
|
462
486
|
user_groups: responseData.user_groups || [],
|
|
463
|
-
user_login_methods: responseData.user_login_methods || []
|
|
487
|
+
user_login_methods: responseData.user_login_methods || [],
|
|
464
488
|
};
|
|
465
489
|
return registrationResponse;
|
|
466
490
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { AppInfo, User, UserGroup, Role, Privilege, CommonOptions } from "../common/types.js";
|
|
2
|
+
export type { AppInfo, UserGroup };
|
|
3
|
+
/**
|
|
4
|
+
* Auth user information (extends User with non-null remark)
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthUser extends Omit<User, "remark"> {
|
|
7
|
+
remark: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* User token information
|
|
11
|
+
*/
|
|
12
|
+
export interface UserToken {
|
|
13
|
+
token: string;
|
|
14
|
+
scope: string;
|
|
15
|
+
device_name?: string;
|
|
16
|
+
device_fingerprint?: string;
|
|
17
|
+
granted_at: string;
|
|
18
|
+
expired_at: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Auth role (extends base Role with additional fields)
|
|
22
|
+
*/
|
|
23
|
+
export interface AuthRole extends Role {
|
|
24
|
+
assigned_at: string;
|
|
25
|
+
expires_at?: string;
|
|
26
|
+
is_active: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Auth privilege (extends base Privilege with additional fields)
|
|
30
|
+
*/
|
|
31
|
+
export interface AuthPrivilege extends Privilege {
|
|
32
|
+
granted_directly: boolean;
|
|
33
|
+
role_id?: string;
|
|
34
|
+
assigned_at: string;
|
|
35
|
+
expires_at?: string;
|
|
36
|
+
is_active: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Auth user login method
|
|
40
|
+
*/
|
|
41
|
+
export interface AuthUserLoginMethod {
|
|
42
|
+
method_type: string;
|
|
43
|
+
identifier: string;
|
|
44
|
+
is_active: boolean;
|
|
45
|
+
created_at: string;
|
|
46
|
+
last_used_at?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface LoginRequest {
|
|
49
|
+
username: string;
|
|
50
|
+
password: string;
|
|
51
|
+
}
|
|
52
|
+
export interface LoginOptions {
|
|
53
|
+
baseUrl?: string;
|
|
54
|
+
device_name?: string;
|
|
55
|
+
device_fingerprint?: string;
|
|
56
|
+
scope?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LoginResponse {
|
|
59
|
+
app: AppInfo;
|
|
60
|
+
user: AuthUser;
|
|
61
|
+
token: UserToken;
|
|
62
|
+
user_roles: AuthRole[];
|
|
63
|
+
user_privileges: AuthPrivilege[];
|
|
64
|
+
user_groups: UserGroup[];
|
|
65
|
+
user_login_methods: AuthUserLoginMethod[];
|
|
66
|
+
}
|
|
67
|
+
export interface LoginJson {
|
|
68
|
+
app: AppInfo;
|
|
69
|
+
user: AuthUser;
|
|
70
|
+
token: UserToken;
|
|
71
|
+
user_roles: AuthRole[];
|
|
72
|
+
user_privileges: AuthPrivilege[];
|
|
73
|
+
user_groups: UserGroup[];
|
|
74
|
+
user_login_methods: AuthUserLoginMethod[];
|
|
75
|
+
}
|
|
76
|
+
export interface LoginWithSmsOptions {
|
|
77
|
+
appToken?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface VerifySmsOptions extends CommonOptions {
|
|
80
|
+
device_name?: string;
|
|
81
|
+
device_fingerprint?: string;
|
|
82
|
+
scope?: string;
|
|
83
|
+
}
|
|
84
|
+
export interface SendSmsResponse {
|
|
85
|
+
app_key: string;
|
|
86
|
+
phone: string;
|
|
87
|
+
type: "login" | "register";
|
|
88
|
+
sms_id: string;
|
|
89
|
+
expired_at: string;
|
|
90
|
+
}
|
|
91
|
+
export interface SendSmsJson {
|
|
92
|
+
app_key: string;
|
|
93
|
+
phone: string;
|
|
94
|
+
type: "login" | "register";
|
|
95
|
+
sms_id: string;
|
|
96
|
+
expired_at: string;
|
|
97
|
+
}
|
|
98
|
+
export interface VerifySmsRequest {
|
|
99
|
+
sms_id: string;
|
|
100
|
+
sms_type: "login" | "register";
|
|
101
|
+
verification_code: string;
|
|
102
|
+
username?: string;
|
|
103
|
+
password_encrypted?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface SmsLoginResponse {
|
|
106
|
+
app: AppInfo;
|
|
107
|
+
user: AuthUser;
|
|
108
|
+
token: UserToken;
|
|
109
|
+
user_roles: AuthRole[];
|
|
110
|
+
user_privileges: AuthPrivilege[];
|
|
111
|
+
user_groups: UserGroup[];
|
|
112
|
+
user_login_methods: AuthUserLoginMethod[];
|
|
113
|
+
}
|
|
114
|
+
export interface SmsLoginJson {
|
|
115
|
+
app: AppInfo;
|
|
116
|
+
user: AuthUser;
|
|
117
|
+
token: UserToken;
|
|
118
|
+
user_roles: AuthRole[];
|
|
119
|
+
user_privileges: AuthPrivilege[];
|
|
120
|
+
user_groups: UserGroup[];
|
|
121
|
+
user_login_methods: AuthUserLoginMethod[];
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|