@allanfsouza/aether-sdk 2.5.1 → 2.5.3
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/ai.d.ts +1 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +1 -0
- package/dist/ai.js.map +1 -0
- package/dist/auth.d.ts +55 -19
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +187 -67
- package/dist/auth.js.map +1 -0
- package/dist/database.d.ts +1 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +1 -0
- package/dist/database.js.map +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -0
- package/dist/functions.d.ts +1 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/functions.js +1 -0
- package/dist/functions.js.map +1 -0
- package/dist/http-client.d.ts +1 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +1 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -20
- package/dist/index.js.map +1 -0
- package/dist/push.d.ts +1 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +1 -0
- package/dist/push.js.map +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +1 -0
- package/dist/storage.js.map +1 -0
- package/dist/tenant-auth.d.ts +1 -0
- package/dist/tenant-auth.d.ts.map +1 -0
- package/dist/tenant-auth.js +1 -0
- package/dist/tenant-auth.js.map +1 -0
- package/package.json +2 -2
- package/src/auth.ts +228 -78
- package/src/index.ts +54 -24
- package/tsconfig.json +16 -8
package/src/auth.ts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
// src/auth.ts
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// MÓDULO DE AUTENTICAÇÃO ADMINISTRATIVA - STANDALONE
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// ⚠️ USO EXCLUSIVO DO WEB-ADMIN - NÃO EXPOSTO NO SDK PÚBLICO
|
|
6
|
+
//
|
|
7
|
+
// Este módulo gerencia autenticação contra a tabela GLOBAL 'users' do Aether
|
|
8
|
+
// (donos de projetos). Apps client-side devem usar TenantAuthModule.
|
|
9
|
+
//
|
|
10
|
+
// IMPORTANTE: Este módulo é STANDALONE - não depende do PlataformaClient.
|
|
11
|
+
// Ele pode ser importado diretamente:
|
|
12
|
+
// import { AuthModule } from "@allanfsouza/aether-sdk/dist/auth";
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
import axios from "axios";
|
|
2
16
|
import type { AxiosInstance } from "axios";
|
|
3
|
-
import type { PlataformaClient } from "./index.js";
|
|
4
17
|
|
|
5
|
-
//
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// INTERFACES
|
|
20
|
+
// =============================================================================
|
|
21
|
+
|
|
6
22
|
export interface User {
|
|
7
23
|
id: string;
|
|
8
24
|
name: string;
|
|
@@ -28,20 +44,74 @@ export interface Session {
|
|
|
28
44
|
expiresAt: string;
|
|
29
45
|
}
|
|
30
46
|
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// CONSTANTES DE STORAGE
|
|
49
|
+
// Usamos chaves DIFERENTES do SDK público para evitar conflito
|
|
50
|
+
// =============================================================================
|
|
51
|
+
const ADMIN_STORAGE_KEYS = {
|
|
52
|
+
TOKEN: "aether_admin_token",
|
|
53
|
+
REFRESH_TOKEN: "aether_admin_refresh",
|
|
54
|
+
USER: "aether_admin_user",
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Verifica se estamos em ambiente browser com localStorage disponível.
|
|
59
|
+
*/
|
|
60
|
+
function isBrowser(): boolean {
|
|
61
|
+
return (
|
|
62
|
+
typeof window !== "undefined" &&
|
|
63
|
+
typeof window.localStorage !== "undefined"
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// =============================================================================
|
|
68
|
+
// CLASSE PRINCIPAL - STANDALONE
|
|
69
|
+
// =============================================================================
|
|
70
|
+
|
|
31
71
|
export class AuthModule {
|
|
32
|
-
private client: PlataformaClient;
|
|
33
72
|
private http: AxiosInstance;
|
|
73
|
+
private apiUrl: string;
|
|
34
74
|
|
|
35
|
-
// Armazena
|
|
36
|
-
// Persistência fica no PlataformaClient (localStorage)
|
|
75
|
+
// Armazena dados em memória para acesso rápido
|
|
37
76
|
private currentUser: User | null = null;
|
|
77
|
+
private accessToken: string | null = null;
|
|
78
|
+
private refreshToken: string | null = null;
|
|
38
79
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Cria uma instância do módulo de autenticação administrativa.
|
|
82
|
+
*
|
|
83
|
+
* @param apiUrl URL base da API do Aether (ex: https://api.aether.dev)
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* import { AuthModule } from "@allanfsouza/aether-sdk/dist/auth";
|
|
88
|
+
*
|
|
89
|
+
* const auth = new AuthModule("https://api.aether.dev");
|
|
90
|
+
* await auth.login("admin@example.com", "password");
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
constructor(apiUrl: string) {
|
|
94
|
+
this.apiUrl = apiUrl.replace(/\/+$/, "");
|
|
95
|
+
|
|
96
|
+
// Cria instância HTTP dedicada para auth admin
|
|
97
|
+
this.http = axios.create({
|
|
98
|
+
baseURL: `${this.apiUrl}/v1`,
|
|
99
|
+
headers: {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Interceptor para adicionar token em todas as requisições
|
|
105
|
+
this.http.interceptors.request.use((config) => {
|
|
106
|
+
const token = this.getToken();
|
|
107
|
+
if (token) {
|
|
108
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
109
|
+
}
|
|
110
|
+
return config;
|
|
111
|
+
});
|
|
42
112
|
|
|
43
|
-
// Restaura
|
|
44
|
-
this.
|
|
113
|
+
// Restaura sessão do localStorage se existir
|
|
114
|
+
this._restoreSession();
|
|
45
115
|
}
|
|
46
116
|
|
|
47
117
|
// ==========================================================================
|
|
@@ -56,18 +126,13 @@ export class AuthModule {
|
|
|
56
126
|
});
|
|
57
127
|
|
|
58
128
|
if (data.accessToken) {
|
|
59
|
-
|
|
60
|
-
this.client.setToken(data.accessToken);
|
|
61
|
-
this.client.setRefreshToken(data.refreshToken);
|
|
62
|
-
this.client.setUser(data.user);
|
|
63
|
-
this.currentUser = data.user;
|
|
129
|
+
this._setSession(data.accessToken, data.refreshToken, data.user);
|
|
64
130
|
}
|
|
65
131
|
|
|
66
132
|
return data;
|
|
67
133
|
} catch (e) {
|
|
68
134
|
// Limpa tudo em caso de erro
|
|
69
|
-
this.
|
|
70
|
-
this.currentUser = null;
|
|
135
|
+
this.clearSession();
|
|
71
136
|
throw e;
|
|
72
137
|
}
|
|
73
138
|
}
|
|
@@ -76,27 +141,22 @@ export class AuthModule {
|
|
|
76
141
|
name: string;
|
|
77
142
|
email: string;
|
|
78
143
|
password: string;
|
|
79
|
-
}) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (data.accessToken) {
|
|
85
|
-
this.client.setToken(data.accessToken);
|
|
86
|
-
this.client.setRefreshToken(data.refreshToken);
|
|
87
|
-
this.client.setUser(data.user);
|
|
88
|
-
this.currentUser = data.user;
|
|
89
|
-
}
|
|
144
|
+
}): Promise<LoginResponse> {
|
|
145
|
+
const { data } = await this.http.post<LoginResponse>(
|
|
146
|
+
"/auth/register",
|
|
147
|
+
credentials
|
|
148
|
+
);
|
|
90
149
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
150
|
+
// Se o register retornar token (auto-login), configura sessão
|
|
151
|
+
if (data.accessToken) {
|
|
152
|
+
this._setSession(data.accessToken, data.refreshToken, data.user);
|
|
94
153
|
}
|
|
154
|
+
|
|
155
|
+
return data;
|
|
95
156
|
}
|
|
96
157
|
|
|
97
|
-
async refresh(): Promise<{ accessToken: string }> {
|
|
98
|
-
|
|
99
|
-
const refreshToken = this.client.getRefreshToken() || this.getRefreshToken();
|
|
158
|
+
async refresh(): Promise<{ accessToken: string; refreshToken?: string }> {
|
|
159
|
+
const refreshToken = this.getRefreshToken();
|
|
100
160
|
|
|
101
161
|
if (!refreshToken) {
|
|
102
162
|
throw new Error("Nenhum refresh token disponível");
|
|
@@ -108,49 +168,48 @@ export class AuthModule {
|
|
|
108
168
|
});
|
|
109
169
|
|
|
110
170
|
if (data.accessToken) {
|
|
111
|
-
this.
|
|
171
|
+
this.accessToken = data.accessToken;
|
|
172
|
+
this._persistToken();
|
|
112
173
|
|
|
113
174
|
// Se vier novo refresh token, atualiza
|
|
114
175
|
if (data.refreshToken) {
|
|
115
|
-
this.
|
|
176
|
+
this.refreshToken = data.refreshToken;
|
|
177
|
+
this._persistRefreshToken();
|
|
116
178
|
}
|
|
117
179
|
}
|
|
118
180
|
|
|
119
181
|
return data;
|
|
120
182
|
} catch (e) {
|
|
121
183
|
// Token expirado - limpa sessão
|
|
122
|
-
this.
|
|
123
|
-
this.currentUser = null;
|
|
184
|
+
this.clearSession();
|
|
124
185
|
throw e;
|
|
125
186
|
}
|
|
126
187
|
}
|
|
127
188
|
|
|
128
189
|
getGoogleAuthUrl(): string {
|
|
129
|
-
return `${this.
|
|
190
|
+
return `${this.apiUrl}/v1/auth/google`;
|
|
130
191
|
}
|
|
131
192
|
|
|
132
193
|
async logout(): Promise<void> {
|
|
133
|
-
const refreshToken = this.
|
|
194
|
+
const refreshToken = this.getRefreshToken();
|
|
134
195
|
|
|
135
196
|
if (refreshToken) {
|
|
136
197
|
try {
|
|
137
198
|
await this.http.post("/auth/logout", { refreshToken });
|
|
138
199
|
} catch {
|
|
139
|
-
// Ignora erro de logout no servidor
|
|
200
|
+
// Ignora erro de logout no servidor - limpa local de qualquer forma
|
|
140
201
|
}
|
|
141
202
|
}
|
|
142
203
|
|
|
143
204
|
// Limpa tudo (memória + localStorage)
|
|
144
|
-
this.
|
|
145
|
-
this.currentUser = null;
|
|
205
|
+
this.clearSession();
|
|
146
206
|
}
|
|
147
207
|
|
|
148
208
|
async logoutAll(): Promise<void> {
|
|
149
209
|
try {
|
|
150
210
|
await this.http.post("/auth/logout-all");
|
|
151
211
|
} finally {
|
|
152
|
-
this.
|
|
153
|
-
this.currentUser = null;
|
|
212
|
+
this.clearSession();
|
|
154
213
|
}
|
|
155
214
|
}
|
|
156
215
|
|
|
@@ -161,12 +220,15 @@ export class AuthModule {
|
|
|
161
220
|
return data.sessions;
|
|
162
221
|
}
|
|
163
222
|
|
|
164
|
-
async forgotPassword(email: string) {
|
|
223
|
+
async forgotPassword(email: string): Promise<{ message: string }> {
|
|
165
224
|
const { data } = await this.http.post("/auth/forgot-password", { email });
|
|
166
225
|
return data;
|
|
167
226
|
}
|
|
168
227
|
|
|
169
|
-
async resetPassword(
|
|
228
|
+
async resetPassword(
|
|
229
|
+
token: string,
|
|
230
|
+
newPassword: string
|
|
231
|
+
): Promise<{ message: string }> {
|
|
170
232
|
const { data } = await this.http.post("/auth/reset-password", {
|
|
171
233
|
token,
|
|
172
234
|
newPassword,
|
|
@@ -174,18 +236,34 @@ export class AuthModule {
|
|
|
174
236
|
return data;
|
|
175
237
|
}
|
|
176
238
|
|
|
239
|
+
// ==========================================================================
|
|
240
|
+
// GETTERS DE SESSÃO
|
|
241
|
+
// ==========================================================================
|
|
242
|
+
|
|
243
|
+
getToken(): string | null {
|
|
244
|
+
return this.accessToken;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
getRefreshToken(): string | null {
|
|
248
|
+
return this.refreshToken;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
getUser(): User | null {
|
|
252
|
+
return this.currentUser;
|
|
253
|
+
}
|
|
254
|
+
|
|
177
255
|
/**
|
|
178
|
-
*
|
|
256
|
+
* Alias para getUser() - compatibilidade com código existente.
|
|
179
257
|
*/
|
|
180
|
-
|
|
181
|
-
return this.
|
|
258
|
+
getCurrentUser(): User | null {
|
|
259
|
+
return this.currentUser;
|
|
182
260
|
}
|
|
183
261
|
|
|
184
262
|
/**
|
|
185
|
-
*
|
|
263
|
+
* Verifica se existe uma sessão ativa.
|
|
186
264
|
*/
|
|
187
|
-
|
|
188
|
-
this.
|
|
265
|
+
isAuthenticated(): boolean {
|
|
266
|
+
return this.accessToken !== null && this.currentUser !== null;
|
|
189
267
|
}
|
|
190
268
|
|
|
191
269
|
// ==========================================================================
|
|
@@ -199,8 +277,9 @@ export class AuthModule {
|
|
|
199
277
|
try {
|
|
200
278
|
const data = await this.login(credentials.email, credentials.password);
|
|
201
279
|
return { user: data.user, error: null };
|
|
202
|
-
} catch (err:
|
|
203
|
-
|
|
280
|
+
} catch (err: unknown) {
|
|
281
|
+
const error = err as { response?: { data?: { message?: string } }; message?: string };
|
|
282
|
+
return { user: null, error: error.response?.data?.message || error.message };
|
|
204
283
|
}
|
|
205
284
|
}
|
|
206
285
|
|
|
@@ -219,8 +298,9 @@ export class AuthModule {
|
|
|
219
298
|
name: credentials.data?.name || credentials.email.split("@")[0],
|
|
220
299
|
});
|
|
221
300
|
return { user: data.user, error: null };
|
|
222
|
-
} catch (err:
|
|
223
|
-
|
|
301
|
+
} catch (err: unknown) {
|
|
302
|
+
const error = err as { response?: { data?: { message?: string } }; message?: string };
|
|
303
|
+
return { user: null, error: error.response?.data?.message || error.message };
|
|
224
304
|
}
|
|
225
305
|
}
|
|
226
306
|
|
|
@@ -237,8 +317,8 @@ export class AuthModule {
|
|
|
237
317
|
* Primeiro tenta memória, depois localStorage.
|
|
238
318
|
* Se não encontrar, retorna null.
|
|
239
319
|
*/
|
|
240
|
-
async getSession() {
|
|
241
|
-
const token = this.
|
|
320
|
+
async getSession(): Promise<{ user: User; access_token: string } | null> {
|
|
321
|
+
const token = this.getToken();
|
|
242
322
|
if (!token) return null;
|
|
243
323
|
|
|
244
324
|
// Tenta memória primeiro
|
|
@@ -249,38 +329,108 @@ export class AuthModule {
|
|
|
249
329
|
};
|
|
250
330
|
}
|
|
251
331
|
|
|
252
|
-
// Tenta localStorage
|
|
253
|
-
const savedUser = this.client.getUser();
|
|
254
|
-
if (savedUser) {
|
|
255
|
-
this.currentUser = savedUser;
|
|
256
|
-
return {
|
|
257
|
-
user: savedUser,
|
|
258
|
-
access_token: token,
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
332
|
// Última opção: valida token no backend
|
|
263
333
|
try {
|
|
264
334
|
const { data } = await this.http.get<{ user: User }>("/auth/me");
|
|
265
335
|
this.currentUser = data.user;
|
|
266
|
-
this.
|
|
336
|
+
this._persistUser();
|
|
267
337
|
return {
|
|
268
338
|
user: data.user,
|
|
269
339
|
access_token: token,
|
|
270
340
|
};
|
|
271
341
|
} catch {
|
|
272
342
|
// Token inválido/expirado - limpa sessão
|
|
273
|
-
this.
|
|
274
|
-
this.currentUser = null;
|
|
343
|
+
this.clearSession();
|
|
275
344
|
return null;
|
|
276
345
|
}
|
|
277
346
|
}
|
|
278
347
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
348
|
+
// ==========================================================================
|
|
349
|
+
// GERENCIAMENTO DE SESSÃO (INTERNO)
|
|
350
|
+
// ==========================================================================
|
|
351
|
+
|
|
352
|
+
clearSession(): void {
|
|
353
|
+
this.accessToken = null;
|
|
354
|
+
this.refreshToken = null;
|
|
355
|
+
this.currentUser = null;
|
|
356
|
+
|
|
357
|
+
if (isBrowser()) {
|
|
358
|
+
localStorage.removeItem(ADMIN_STORAGE_KEYS.TOKEN);
|
|
359
|
+
localStorage.removeItem(ADMIN_STORAGE_KEYS.REFRESH_TOKEN);
|
|
360
|
+
localStorage.removeItem(ADMIN_STORAGE_KEYS.USER);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
private _setSession(token: string, refresh: string, user: User): void {
|
|
365
|
+
this.accessToken = token;
|
|
366
|
+
this.refreshToken = refresh;
|
|
367
|
+
this.currentUser = user;
|
|
368
|
+
this._persistAll();
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
private _persistAll(): void {
|
|
372
|
+
this._persistToken();
|
|
373
|
+
this._persistRefreshToken();
|
|
374
|
+
this._persistUser();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
private _persistToken(): void {
|
|
378
|
+
if (isBrowser() && this.accessToken) {
|
|
379
|
+
localStorage.setItem(ADMIN_STORAGE_KEYS.TOKEN, this.accessToken);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private _persistRefreshToken(): void {
|
|
384
|
+
if (isBrowser() && this.refreshToken) {
|
|
385
|
+
localStorage.setItem(ADMIN_STORAGE_KEYS.REFRESH_TOKEN, this.refreshToken);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private _persistUser(): void {
|
|
390
|
+
if (isBrowser() && this.currentUser) {
|
|
391
|
+
localStorage.setItem(
|
|
392
|
+
ADMIN_STORAGE_KEYS.USER,
|
|
393
|
+
JSON.stringify(this.currentUser)
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
private _restoreSession(): void {
|
|
399
|
+
if (!isBrowser()) return;
|
|
400
|
+
|
|
401
|
+
const token = localStorage.getItem(ADMIN_STORAGE_KEYS.TOKEN);
|
|
402
|
+
const refresh = localStorage.getItem(ADMIN_STORAGE_KEYS.REFRESH_TOKEN);
|
|
403
|
+
const userJson = localStorage.getItem(ADMIN_STORAGE_KEYS.USER);
|
|
404
|
+
|
|
405
|
+
if (token) this.accessToken = token;
|
|
406
|
+
if (refresh) this.refreshToken = refresh;
|
|
407
|
+
|
|
408
|
+
if (userJson) {
|
|
409
|
+
try {
|
|
410
|
+
this.currentUser = JSON.parse(userJson);
|
|
411
|
+
} catch {
|
|
412
|
+
// JSON inválido - limpa o dado corrompido
|
|
413
|
+
localStorage.removeItem(ADMIN_STORAGE_KEYS.USER);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
285
416
|
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// =============================================================================
|
|
420
|
+
// FACTORY FUNCTION (Alternativa ao construtor)
|
|
421
|
+
// =============================================================================
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Cria uma instância do módulo de autenticação administrativa.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```typescript
|
|
428
|
+
* import { createAdminAuth } from "@allanfsouza/aether-sdk/dist/auth";
|
|
429
|
+
*
|
|
430
|
+
* const auth = createAdminAuth("https://api.aether.dev");
|
|
431
|
+
* await auth.login("admin@example.com", "password");
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
export function createAdminAuth(apiUrl: string): AuthModule {
|
|
435
|
+
return new AuthModule(apiUrl);
|
|
286
436
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// AETHER SDK - Cliente Principal
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// SEGURANÇA: AuthModule foi REMOVIDO do SDK público.
|
|
6
|
+
// O módulo auth é exclusivo para o painel administrativo do Aether (web-admin).
|
|
7
|
+
// Apps client-side devem usar APENAS tenantAuth para autenticar seus usuários.
|
|
8
|
+
// =============================================================================
|
|
9
|
+
|
|
2
10
|
import type { AxiosInstance } from "axios";
|
|
3
11
|
import { createHttpClient } from "./http-client.js";
|
|
4
|
-
import { AuthModule, User } from "./auth.js";
|
|
5
12
|
import { DatabaseModule } from "./database.js";
|
|
6
13
|
import { StorageModule } from "./storage.js";
|
|
7
14
|
import { FunctionsModule } from "./functions.js";
|
|
8
15
|
import { PushModule } from "./push.js";
|
|
9
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
TenantAuthModule,
|
|
18
|
+
type TenantUser,
|
|
19
|
+
type TenantLoginResponse,
|
|
20
|
+
type TenantRegisterCredentials,
|
|
21
|
+
type TenantLoginCredentials,
|
|
22
|
+
} from "./tenant-auth.js";
|
|
10
23
|
import { AIModule } from "./ai.js";
|
|
11
24
|
|
|
12
25
|
// =============================================================================
|
|
@@ -30,7 +43,7 @@ export type ClientConfig = {
|
|
|
30
43
|
apiKey?: string;
|
|
31
44
|
|
|
32
45
|
/**
|
|
33
|
-
*
|
|
46
|
+
* API Key de serviço para autenticação em operações de banco de dados.
|
|
34
47
|
* Necessário para apps client-side que usam tenant auth.
|
|
35
48
|
*/
|
|
36
49
|
serviceApiKey?: string;
|
|
@@ -54,7 +67,15 @@ function isBrowser(): boolean {
|
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
export class PlataformaClient {
|
|
57
|
-
|
|
70
|
+
// =========================================================================
|
|
71
|
+
// MÓDULOS PÚBLICOS
|
|
72
|
+
// =========================================================================
|
|
73
|
+
// NOTA DE SEGURANÇA: AuthModule foi REMOVIDO intencionalmente.
|
|
74
|
+
// Ele gerencia a tabela GLOBAL 'users' (donos de projetos Aether).
|
|
75
|
+
// Apps client-side NÃO devem ter acesso a essa funcionalidade.
|
|
76
|
+
// Use tenantAuth para autenticar usuários dos seus apps.
|
|
77
|
+
// =========================================================================
|
|
78
|
+
|
|
58
79
|
public db: DatabaseModule;
|
|
59
80
|
public storage: StorageModule;
|
|
60
81
|
public functions: FunctionsModule;
|
|
@@ -96,8 +117,12 @@ export class PlataformaClient {
|
|
|
96
117
|
|
|
97
118
|
this.http = createHttpClient(this);
|
|
98
119
|
|
|
99
|
-
//
|
|
100
|
-
|
|
120
|
+
// =========================================================================
|
|
121
|
+
// INICIALIZAÇÃO DOS MÓDULOS
|
|
122
|
+
// =========================================================================
|
|
123
|
+
// SEGURANÇA: AuthModule NÃO é inicializado aqui.
|
|
124
|
+
// Apenas módulos seguros para client-side são expostos.
|
|
125
|
+
// =========================================================================
|
|
101
126
|
this.db = new DatabaseModule(this, this.http);
|
|
102
127
|
this.storage = new StorageModule(this, this.http);
|
|
103
128
|
this.functions = new FunctionsModule(this, this.http);
|
|
@@ -142,7 +167,7 @@ export class PlataformaClient {
|
|
|
142
167
|
|
|
143
168
|
/**
|
|
144
169
|
* Salva o refresh token.
|
|
145
|
-
* Usado internamente pelo
|
|
170
|
+
* Usado internamente pelo TenantAuthModule após login.
|
|
146
171
|
*/
|
|
147
172
|
setRefreshToken(token: string | null): void {
|
|
148
173
|
if (this._persistSession && isBrowser()) {
|
|
@@ -158,20 +183,21 @@ export class PlataformaClient {
|
|
|
158
183
|
* Retorna o refresh token salvo no localStorage.
|
|
159
184
|
*/
|
|
160
185
|
getRefreshToken(): string | null {
|
|
161
|
-
if (
|
|
186
|
+
if (isBrowser()) {
|
|
162
187
|
return localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN);
|
|
163
188
|
}
|
|
164
189
|
return null;
|
|
165
190
|
}
|
|
166
191
|
|
|
167
192
|
// ===========================================================================
|
|
168
|
-
//
|
|
193
|
+
// USER DATA (TENANT USER)
|
|
169
194
|
// ===========================================================================
|
|
170
195
|
|
|
171
196
|
/**
|
|
172
|
-
* Salva dados do usuário
|
|
197
|
+
* Salva dados do usuário tenant no localStorage.
|
|
198
|
+
* Usado internamente pelo TenantAuthModule após login.
|
|
173
199
|
*/
|
|
174
|
-
setUser(user:
|
|
200
|
+
setUser(user: TenantUser | null): void {
|
|
175
201
|
if (this._persistSession && isBrowser()) {
|
|
176
202
|
if (user) {
|
|
177
203
|
localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(user));
|
|
@@ -182,19 +208,18 @@ export class PlataformaClient {
|
|
|
182
208
|
}
|
|
183
209
|
|
|
184
210
|
/**
|
|
185
|
-
* Retorna dados do usuário
|
|
211
|
+
* Retorna dados do usuário tenant salvos no localStorage.
|
|
186
212
|
*/
|
|
187
|
-
getUser():
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return JSON.parse(
|
|
193
|
-
} catch {
|
|
194
|
-
// JSON corrompido - limpa
|
|
195
|
-
localStorage.removeItem(STORAGE_KEYS.USER);
|
|
196
|
-
return null;
|
|
213
|
+
getUser(): TenantUser | null {
|
|
214
|
+
if (isBrowser()) {
|
|
215
|
+
try {
|
|
216
|
+
const raw = localStorage.getItem(STORAGE_KEYS.USER);
|
|
217
|
+
if (raw) {
|
|
218
|
+
return JSON.parse(raw) as TenantUser;
|
|
197
219
|
}
|
|
220
|
+
} catch {
|
|
221
|
+
// JSON inválido - limpa o dado corrompido
|
|
222
|
+
localStorage.removeItem(STORAGE_KEYS.USER);
|
|
198
223
|
}
|
|
199
224
|
}
|
|
200
225
|
return null;
|
|
@@ -241,9 +266,14 @@ export class PlataformaClient {
|
|
|
241
266
|
}
|
|
242
267
|
}
|
|
243
268
|
|
|
244
|
-
//
|
|
269
|
+
// =============================================================================
|
|
270
|
+
// EXPORTS PÚBLICOS
|
|
271
|
+
// =============================================================================
|
|
272
|
+
// NOTA: Tipos do auth.ts (User, LoginResponse, Session) foram REMOVIDOS
|
|
273
|
+
// pois pertencem ao módulo administrativo, não ao SDK público.
|
|
274
|
+
// =============================================================================
|
|
275
|
+
|
|
245
276
|
export { AetherError } from "./errors.js";
|
|
246
|
-
export type { LoginResponse, Session, User } from "./auth.js";
|
|
247
277
|
export type { ListOptions } from "./database.js";
|
|
248
278
|
export type {
|
|
249
279
|
PushPlatform,
|
package/tsconfig.json
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES2020",
|
|
4
|
-
"module": "
|
|
5
|
-
"moduleResolution": "
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2020",
|
|
8
|
+
"DOM"
|
|
9
|
+
],
|
|
6
10
|
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"sourceMap": true,
|
|
7
13
|
"outDir": "./dist",
|
|
8
14
|
"rootDir": "./src",
|
|
9
15
|
"strict": true,
|
|
16
|
+
"esModuleInterop": true,
|
|
10
17
|
"skipLibCheck": true,
|
|
11
18
|
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
"ES2020",
|
|
15
|
-
"DOM"
|
|
16
|
-
]
|
|
19
|
+
"resolveJsonModule": true,
|
|
20
|
+
"allowSyntheticDefaultImports": true
|
|
17
21
|
},
|
|
18
22
|
"include": [
|
|
19
|
-
"src"
|
|
23
|
+
"src/**/*.ts"
|
|
24
|
+
],
|
|
25
|
+
"exclude": [
|
|
26
|
+
"node_modules",
|
|
27
|
+
"dist"
|
|
20
28
|
]
|
|
21
29
|
}
|