@tspvivek/baasix-sdk 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +942 -0
- package/dist/client-CzF9B60b.d.ts +614 -0
- package/dist/client-aXK_gEyr.d.cts +614 -0
- package/dist/index.cjs +4159 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1498 -0
- package/dist/index.d.ts +1498 -0
- package/dist/index.js +4135 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/auth.cjs +651 -0
- package/dist/modules/auth.cjs.map +1 -0
- package/dist/modules/auth.d.cts +384 -0
- package/dist/modules/auth.d.ts +384 -0
- package/dist/modules/auth.js +649 -0
- package/dist/modules/auth.js.map +1 -0
- package/dist/modules/files.cjs +266 -0
- package/dist/modules/files.cjs.map +1 -0
- package/dist/modules/files.d.cts +187 -0
- package/dist/modules/files.d.ts +187 -0
- package/dist/modules/files.js +264 -0
- package/dist/modules/files.js.map +1 -0
- package/dist/modules/items.cjs +654 -0
- package/dist/modules/items.cjs.map +1 -0
- package/dist/modules/items.d.cts +472 -0
- package/dist/modules/items.d.ts +472 -0
- package/dist/modules/items.js +651 -0
- package/dist/modules/items.js.map +1 -0
- package/dist/modules/schemas.cjs +269 -0
- package/dist/modules/schemas.cjs.map +1 -0
- package/dist/modules/schemas.d.cts +239 -0
- package/dist/modules/schemas.d.ts +239 -0
- package/dist/modules/schemas.js +267 -0
- package/dist/modules/schemas.js.map +1 -0
- package/dist/storage/index.cjs +162 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +96 -0
- package/dist/storage/index.d.ts +96 -0
- package/dist/storage/index.js +157 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-BdjsGANq.d.cts +40 -0
- package/dist/types-BdjsGANq.d.ts +40 -0
- package/package.json +107 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
// src/storage/types.ts
|
|
2
|
+
var STORAGE_KEYS = {
|
|
3
|
+
ACCESS_TOKEN: "baasix_access_token",
|
|
4
|
+
REFRESH_TOKEN: "baasix_refresh_token",
|
|
5
|
+
TOKEN_EXPIRY: "baasix_token_expiry",
|
|
6
|
+
USER: "baasix_user",
|
|
7
|
+
TENANT: "baasix_tenant"
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// src/types.ts
|
|
11
|
+
var BaasixError = class _BaasixError extends Error {
|
|
12
|
+
status;
|
|
13
|
+
code;
|
|
14
|
+
details;
|
|
15
|
+
isRetryable;
|
|
16
|
+
constructor(message, status = 500, code, details) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "BaasixError";
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.details = details;
|
|
22
|
+
this.isRetryable = status >= 500 || status === 429;
|
|
23
|
+
if (Error.captureStackTrace) {
|
|
24
|
+
Error.captureStackTrace(this, _BaasixError);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
toJSON() {
|
|
28
|
+
return {
|
|
29
|
+
name: this.name,
|
|
30
|
+
message: this.message,
|
|
31
|
+
status: this.status,
|
|
32
|
+
code: this.code,
|
|
33
|
+
details: this.details
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/modules/auth.ts
|
|
39
|
+
var AuthModule = class {
|
|
40
|
+
client;
|
|
41
|
+
storage;
|
|
42
|
+
authMode;
|
|
43
|
+
onAuthStateChange;
|
|
44
|
+
currentUser = null;
|
|
45
|
+
constructor(config) {
|
|
46
|
+
this.client = config.client;
|
|
47
|
+
this.storage = config.storage;
|
|
48
|
+
this.authMode = config.authMode;
|
|
49
|
+
this.onAuthStateChange = config.onAuthStateChange;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Emit an authentication state change event
|
|
53
|
+
*/
|
|
54
|
+
emitAuthStateChange(event, user) {
|
|
55
|
+
this.currentUser = user;
|
|
56
|
+
this.onAuthStateChange?.(event, user);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Store authentication tokens
|
|
60
|
+
*/
|
|
61
|
+
async storeTokens(response) {
|
|
62
|
+
if (this.authMode === "jwt") {
|
|
63
|
+
await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, response.token);
|
|
64
|
+
if (response.refreshToken) {
|
|
65
|
+
await this.storage.set(STORAGE_KEYS.REFRESH_TOKEN, response.refreshToken);
|
|
66
|
+
}
|
|
67
|
+
if (response.expiresIn) {
|
|
68
|
+
const expiresAt = Date.now() + response.expiresIn * 1e3;
|
|
69
|
+
await this.storage.set(STORAGE_KEYS.TOKEN_EXPIRY, expiresAt.toString());
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (response.user) {
|
|
73
|
+
await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Clear stored authentication data
|
|
78
|
+
*/
|
|
79
|
+
async clearAuth() {
|
|
80
|
+
await this.storage.remove(STORAGE_KEYS.ACCESS_TOKEN);
|
|
81
|
+
await this.storage.remove(STORAGE_KEYS.REFRESH_TOKEN);
|
|
82
|
+
await this.storage.remove(STORAGE_KEYS.TOKEN_EXPIRY);
|
|
83
|
+
await this.storage.remove(STORAGE_KEYS.USER);
|
|
84
|
+
await this.storage.remove(STORAGE_KEYS.TENANT);
|
|
85
|
+
this.currentUser = null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Register a new user
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const { user, token } = await baasix.auth.register({
|
|
93
|
+
* email: 'newuser@example.com',
|
|
94
|
+
* password: 'securepassword',
|
|
95
|
+
* firstName: 'John',
|
|
96
|
+
* lastName: 'Doe'
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
async register(data) {
|
|
101
|
+
const response = await this.client.post("/auth/register", data, {
|
|
102
|
+
skipAuth: true
|
|
103
|
+
});
|
|
104
|
+
await this.storeTokens(response);
|
|
105
|
+
this.emitAuthStateChange("SIGNED_IN", response.user);
|
|
106
|
+
return response;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Login with email and password
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const { user, token } = await baasix.auth.login({
|
|
114
|
+
* email: 'user@example.com',
|
|
115
|
+
* password: 'password123'
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* // Login with tenant (multi-tenant mode)
|
|
119
|
+
* const result = await baasix.auth.login({
|
|
120
|
+
* email: 'user@example.com',
|
|
121
|
+
* password: 'password123',
|
|
122
|
+
* tenantId: 'tenant-uuid'
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
async login(credentials) {
|
|
127
|
+
const response = await this.client.post(
|
|
128
|
+
"/auth/login",
|
|
129
|
+
{
|
|
130
|
+
email: credentials.email,
|
|
131
|
+
password: credentials.password,
|
|
132
|
+
tenant_Id: credentials.tenantId
|
|
133
|
+
},
|
|
134
|
+
{ skipAuth: true }
|
|
135
|
+
);
|
|
136
|
+
await this.storeTokens(response);
|
|
137
|
+
this.emitAuthStateChange("SIGNED_IN", response.user);
|
|
138
|
+
return response;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Logout the current user
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* await baasix.auth.logout();
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
async logout() {
|
|
149
|
+
try {
|
|
150
|
+
await this.client.get("/auth/logout");
|
|
151
|
+
} catch {
|
|
152
|
+
}
|
|
153
|
+
await this.clearAuth();
|
|
154
|
+
this.emitAuthStateChange("SIGNED_OUT", null);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get the current authenticated user from the server
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const user = await baasix.auth.getUser();
|
|
162
|
+
* console.log(user?.email);
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
async getUser() {
|
|
166
|
+
try {
|
|
167
|
+
const response = await this.client.get("/auth/me");
|
|
168
|
+
this.currentUser = response.data;
|
|
169
|
+
await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.data));
|
|
170
|
+
return response.data;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error instanceof BaasixError && error.status === 401) {
|
|
173
|
+
await this.clearAuth();
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get the cached current user (does not make an API call)
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const user = await baasix.auth.getCachedUser();
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
async getCachedUser() {
|
|
188
|
+
if (this.currentUser) {
|
|
189
|
+
return this.currentUser;
|
|
190
|
+
}
|
|
191
|
+
const userJson = await this.storage.get(STORAGE_KEYS.USER);
|
|
192
|
+
if (userJson) {
|
|
193
|
+
try {
|
|
194
|
+
this.currentUser = JSON.parse(userJson);
|
|
195
|
+
return this.currentUser;
|
|
196
|
+
} catch {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if user is authenticated (has valid token)
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* if (await baasix.auth.isAuthenticated()) {
|
|
208
|
+
* // User is logged in
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
async isAuthenticated() {
|
|
213
|
+
if (this.authMode === "cookie") {
|
|
214
|
+
const user = await this.getCachedUser();
|
|
215
|
+
return user !== null;
|
|
216
|
+
}
|
|
217
|
+
const token = await this.storage.get(STORAGE_KEYS.ACCESS_TOKEN);
|
|
218
|
+
if (!token) return false;
|
|
219
|
+
const expiry = await this.storage.get(STORAGE_KEYS.TOKEN_EXPIRY);
|
|
220
|
+
if (expiry && Date.now() >= parseInt(expiry, 10)) {
|
|
221
|
+
const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
222
|
+
return !!refreshToken;
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the current access token
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* const token = await baasix.auth.getToken();
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
async getToken() {
|
|
235
|
+
if (this.authMode === "cookie") {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return await this.storage.get(STORAGE_KEYS.ACCESS_TOKEN);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Set a static token (useful for server-side or service accounts)
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* baasix.auth.setToken('your-api-token');
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
async setToken(token) {
|
|
249
|
+
await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, token);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Refresh the current token
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* const tokens = await baasix.auth.refreshToken();
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
async refreshToken() {
|
|
260
|
+
const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN);
|
|
261
|
+
const response = await this.client.post(
|
|
262
|
+
"/auth/refresh",
|
|
263
|
+
this.authMode === "jwt" ? { refreshToken } : void 0
|
|
264
|
+
);
|
|
265
|
+
await this.storeTokens(response);
|
|
266
|
+
const tokens = {
|
|
267
|
+
accessToken: response.token,
|
|
268
|
+
refreshToken: response.refreshToken,
|
|
269
|
+
expiresIn: response.expiresIn,
|
|
270
|
+
expiresAt: response.expiresIn ? Date.now() + response.expiresIn * 1e3 : void 0
|
|
271
|
+
};
|
|
272
|
+
this.emitAuthStateChange("TOKEN_REFRESHED", response.user);
|
|
273
|
+
return tokens;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Request a magic link for passwordless login
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* await baasix.auth.sendMagicLink({
|
|
281
|
+
* email: 'user@example.com',
|
|
282
|
+
* redirectUrl: 'https://myapp.com/auth/callback'
|
|
283
|
+
* });
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
async sendMagicLink(options) {
|
|
287
|
+
await this.client.post(
|
|
288
|
+
"/auth/magiclink",
|
|
289
|
+
{
|
|
290
|
+
email: options.email,
|
|
291
|
+
link: options.redirectUrl,
|
|
292
|
+
mode: options.mode || "link"
|
|
293
|
+
},
|
|
294
|
+
{ skipAuth: true }
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Verify magic link/code and complete login
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* ```typescript
|
|
302
|
+
* const { user, token } = await baasix.auth.verifyMagicLink('verification-token');
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
async verifyMagicLink(token) {
|
|
306
|
+
const response = await this.client.post(
|
|
307
|
+
"/auth/magiclink/verify",
|
|
308
|
+
{ token },
|
|
309
|
+
{ skipAuth: true }
|
|
310
|
+
);
|
|
311
|
+
await this.storeTokens(response);
|
|
312
|
+
this.emitAuthStateChange("SIGNED_IN", response.user);
|
|
313
|
+
return response;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Request a password reset
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* await baasix.auth.forgotPassword({
|
|
321
|
+
* email: 'user@example.com',
|
|
322
|
+
* redirectUrl: 'https://myapp.com/reset-password'
|
|
323
|
+
* });
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
async forgotPassword(options) {
|
|
327
|
+
await this.client.post(
|
|
328
|
+
"/auth/forgot-password",
|
|
329
|
+
{
|
|
330
|
+
email: options.email,
|
|
331
|
+
link: options.redirectUrl
|
|
332
|
+
},
|
|
333
|
+
{ skipAuth: true }
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Reset password using a reset token
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* await baasix.auth.resetPassword('reset-token', 'newpassword123');
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
async resetPassword(token, newPassword) {
|
|
345
|
+
await this.client.post(
|
|
346
|
+
"/auth/reset-password",
|
|
347
|
+
{ token, password: newPassword },
|
|
348
|
+
{ skipAuth: true }
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Change the current user's password
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```typescript
|
|
356
|
+
* await baasix.auth.changePassword('currentPassword', 'newPassword');
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
async changePassword(currentPassword, newPassword) {
|
|
360
|
+
await this.client.post("/auth/change-password", {
|
|
361
|
+
currentPassword,
|
|
362
|
+
newPassword
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Update the current user's profile
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* const updatedUser = await baasix.auth.updateProfile({
|
|
371
|
+
* firstName: 'Jane',
|
|
372
|
+
* lastName: 'Doe'
|
|
373
|
+
* });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
async updateProfile(data) {
|
|
377
|
+
const response = await this.client.patch("/auth/me", data);
|
|
378
|
+
await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.data));
|
|
379
|
+
this.emitAuthStateChange("USER_UPDATED", response.data);
|
|
380
|
+
return response.data;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Get available tenants for the current user (multi-tenant mode)
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* const tenants = await baasix.auth.getTenants();
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
async getTenants() {
|
|
391
|
+
const response = await this.client.get("/auth/tenants");
|
|
392
|
+
return response.data;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Switch to a different tenant (multi-tenant mode)
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```typescript
|
|
399
|
+
* const { user, token } = await baasix.auth.switchTenant('tenant-uuid');
|
|
400
|
+
* ```
|
|
401
|
+
*/
|
|
402
|
+
async switchTenant(tenantId) {
|
|
403
|
+
const response = await this.client.post("/auth/switch-tenant", {
|
|
404
|
+
tenant_Id: tenantId
|
|
405
|
+
});
|
|
406
|
+
await this.storeTokens(response);
|
|
407
|
+
await this.storage.set(STORAGE_KEYS.TENANT, tenantId);
|
|
408
|
+
this.emitAuthStateChange("TENANT_SWITCHED", response.user);
|
|
409
|
+
return response;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get the current authentication state
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* const state = await baasix.auth.getState();
|
|
417
|
+
* console.log(state.isAuthenticated, state.user);
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
async getState() {
|
|
421
|
+
const isAuthenticated = await this.isAuthenticated();
|
|
422
|
+
const user = await this.getCachedUser();
|
|
423
|
+
return {
|
|
424
|
+
user,
|
|
425
|
+
isAuthenticated,
|
|
426
|
+
isLoading: false,
|
|
427
|
+
error: null
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Initialize authentication state from storage
|
|
432
|
+
* Call this on app startup to restore previous session
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* await baasix.auth.initialize();
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
async initialize() {
|
|
440
|
+
const state = await this.getState();
|
|
441
|
+
if (state.isAuthenticated && state.user) {
|
|
442
|
+
this.emitAuthStateChange("SIGNED_IN", state.user);
|
|
443
|
+
}
|
|
444
|
+
return state;
|
|
445
|
+
}
|
|
446
|
+
// ===================
|
|
447
|
+
// OAuth / Social Login
|
|
448
|
+
// ===================
|
|
449
|
+
/**
|
|
450
|
+
* Get the OAuth authorization URL for a provider
|
|
451
|
+
* Redirect the user to this URL to start the OAuth flow
|
|
452
|
+
*
|
|
453
|
+
* @example
|
|
454
|
+
* ```typescript
|
|
455
|
+
* const url = baasix.auth.getOAuthUrl({
|
|
456
|
+
* provider: 'google',
|
|
457
|
+
* redirectUrl: 'https://myapp.com/auth/callback'
|
|
458
|
+
* });
|
|
459
|
+
* window.location.href = url;
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
getOAuthUrl(options) {
|
|
463
|
+
const baseUrl = this.client.getBaseUrl();
|
|
464
|
+
const params = new URLSearchParams({
|
|
465
|
+
redirect_url: options.redirectUrl
|
|
466
|
+
});
|
|
467
|
+
if (options.scopes?.length) {
|
|
468
|
+
params.set("scopes", options.scopes.join(","));
|
|
469
|
+
}
|
|
470
|
+
if (options.state) {
|
|
471
|
+
params.set("state", options.state);
|
|
472
|
+
}
|
|
473
|
+
return `${baseUrl}/auth/signin/${options.provider}?${params.toString()}`;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Handle OAuth callback and complete login
|
|
477
|
+
* Call this from your callback page with the token from URL
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```typescript
|
|
481
|
+
* // In your callback page
|
|
482
|
+
* const params = new URLSearchParams(window.location.search);
|
|
483
|
+
* const token = params.get('token');
|
|
484
|
+
*
|
|
485
|
+
* if (token) {
|
|
486
|
+
* await baasix.auth.handleOAuthCallback(token);
|
|
487
|
+
* }
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
async handleOAuthCallback(token) {
|
|
491
|
+
await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, token);
|
|
492
|
+
const user = await this.getUser();
|
|
493
|
+
const response = {
|
|
494
|
+
token,
|
|
495
|
+
user
|
|
496
|
+
};
|
|
497
|
+
this.emitAuthStateChange("SIGNED_IN", user);
|
|
498
|
+
return response;
|
|
499
|
+
}
|
|
500
|
+
// ===================
|
|
501
|
+
// Email Verification
|
|
502
|
+
// ===================
|
|
503
|
+
/**
|
|
504
|
+
* Request email verification
|
|
505
|
+
* Sends a verification email to the current user
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```typescript
|
|
509
|
+
* await baasix.auth.requestEmailVerification('https://myapp.com/verify-email');
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
async requestEmailVerification(redirectUrl) {
|
|
513
|
+
await this.client.post("/auth/request-verify-email", {
|
|
514
|
+
link: redirectUrl
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Verify email with token
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```typescript
|
|
522
|
+
* const params = new URLSearchParams(window.location.search);
|
|
523
|
+
* const token = params.get('token');
|
|
524
|
+
*
|
|
525
|
+
* await baasix.auth.verifyEmail(token);
|
|
526
|
+
* ```
|
|
527
|
+
*/
|
|
528
|
+
async verifyEmail(token) {
|
|
529
|
+
await this.client.get("/auth/verify-email", {
|
|
530
|
+
params: { token },
|
|
531
|
+
skipAuth: true
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Check if current session/token is valid
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* const isValid = await baasix.auth.checkSession();
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
async checkSession() {
|
|
543
|
+
try {
|
|
544
|
+
const response = await this.client.get("/auth/check");
|
|
545
|
+
return response.data.valid;
|
|
546
|
+
} catch {
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// ===================
|
|
551
|
+
// Invitation System
|
|
552
|
+
// ===================
|
|
553
|
+
/**
|
|
554
|
+
* Send an invitation to a user (multi-tenant mode)
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```typescript
|
|
558
|
+
* await baasix.auth.sendInvite({
|
|
559
|
+
* email: 'newuser@example.com',
|
|
560
|
+
* roleId: 'role-uuid',
|
|
561
|
+
* tenantId: 'tenant-uuid',
|
|
562
|
+
* redirectUrl: 'https://myapp.com/accept-invite'
|
|
563
|
+
* });
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
async sendInvite(options) {
|
|
567
|
+
await this.client.post("/auth/invite", {
|
|
568
|
+
email: options.email,
|
|
569
|
+
role_Id: options.roleId,
|
|
570
|
+
tenant_Id: options.tenantId,
|
|
571
|
+
link: options.redirectUrl
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Verify an invitation token
|
|
576
|
+
*
|
|
577
|
+
* @example
|
|
578
|
+
* ```typescript
|
|
579
|
+
* const params = new URLSearchParams(window.location.search);
|
|
580
|
+
* const token = params.get('token');
|
|
581
|
+
*
|
|
582
|
+
* const result = await baasix.auth.verifyInvite(token);
|
|
583
|
+
* if (result.valid) {
|
|
584
|
+
* // Show registration form with pre-filled email
|
|
585
|
+
* }
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
async verifyInvite(token, redirectUrl) {
|
|
589
|
+
const response = await this.client.get(
|
|
590
|
+
"/auth/verify-invite",
|
|
591
|
+
{
|
|
592
|
+
params: {
|
|
593
|
+
token,
|
|
594
|
+
link: redirectUrl
|
|
595
|
+
},
|
|
596
|
+
skipAuth: true
|
|
597
|
+
}
|
|
598
|
+
);
|
|
599
|
+
return response.data;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Accept an invitation (for existing users)
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* ```typescript
|
|
606
|
+
* await baasix.auth.acceptInvite(token);
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
async acceptInvite(token) {
|
|
610
|
+
const response = await this.client.post(
|
|
611
|
+
"/auth/accept-invite",
|
|
612
|
+
{ token }
|
|
613
|
+
);
|
|
614
|
+
await this.storeTokens(response);
|
|
615
|
+
this.emitAuthStateChange("SIGNED_IN", response.user);
|
|
616
|
+
return response;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Register with an invitation token
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```typescript
|
|
623
|
+
* const { user, token } = await baasix.auth.registerWithInvite({
|
|
624
|
+
* email: 'user@example.com',
|
|
625
|
+
* password: 'password',
|
|
626
|
+
* firstName: 'John',
|
|
627
|
+
* lastName: 'Doe',
|
|
628
|
+
* inviteToken: 'invite-token'
|
|
629
|
+
* });
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
async registerWithInvite(data) {
|
|
633
|
+
const response = await this.client.post(
|
|
634
|
+
"/auth/register",
|
|
635
|
+
{
|
|
636
|
+
...data,
|
|
637
|
+
inviteToken: data.inviteToken
|
|
638
|
+
},
|
|
639
|
+
{ skipAuth: true }
|
|
640
|
+
);
|
|
641
|
+
await this.storeTokens(response);
|
|
642
|
+
this.emitAuthStateChange("SIGNED_IN", response.user);
|
|
643
|
+
return response;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
export { AuthModule };
|
|
648
|
+
//# sourceMappingURL=auth.js.map
|
|
649
|
+
//# sourceMappingURL=auth.js.map
|