@allanfsouza/aether-sdk 2.4.6 → 2.4.7

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/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { DatabaseModule } from "./database.js";
4
4
  import { StorageModule } from "./storage.js";
5
5
  import { FunctionsModule } from "./functions.js";
6
6
  import { PushModule } from "./push.js";
7
+ import { TenantAuthModule } from "./tenant-auth.js";
7
8
  /**
8
9
  * Configuração usada para criar o cliente principal da plataforma.
9
10
  */
@@ -24,6 +25,7 @@ export declare class PlataformaClient {
24
25
  storage: StorageModule;
25
26
  functions: FunctionsModule;
26
27
  push: PushModule;
28
+ tenantAuth: TenantAuthModule;
27
29
  database: DatabaseModule;
28
30
  apiUrl: string;
29
31
  projectId: string;
@@ -76,3 +78,4 @@ export { AetherError } from "./errors.js";
76
78
  export type { LoginResponse, Session, User } from "./auth.js";
77
79
  export type { ListOptions } from "./database.js";
78
80
  export type { PushPlatform, PushEnvironment, PushDevice, RegisterDeviceParams, SendPushResponse, PushStatus, PushLogEntry, ListPushLogsOptions, PushStats, } from "./push.js";
81
+ export type { TenantUser, TenantLoginResponse, TenantRegisterCredentials, TenantLoginCredentials, } from "./tenant-auth.js";
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { DatabaseModule } from "./database.js";
4
4
  import { StorageModule } from "./storage.js";
5
5
  import { FunctionsModule } from "./functions.js";
6
6
  import { PushModule } from "./push.js";
7
+ import { TenantAuthModule } from "./tenant-auth.js";
7
8
  // =============================================================================
8
9
  // CONSTANTES DE STORAGE
9
10
  // Chaves padronizadas para localStorage - evita conflito com outros SDKs
@@ -44,6 +45,7 @@ export class PlataformaClient {
44
45
  this.storage = new StorageModule(this, this.http);
45
46
  this.functions = new FunctionsModule(this, this.http);
46
47
  this.push = new PushModule(this, this.http);
48
+ this.tenantAuth = new TenantAuthModule(this, this.http);
47
49
  // Cria o alias que o Showcase App espera
48
50
  this.database = this.db;
49
51
  }
@@ -0,0 +1,172 @@
1
+ import type { AxiosInstance } from "axios";
2
+ import type { PlataformaClient } from "./index.js";
3
+ /**
4
+ * Representa um usuário tenant (end-user de um projeto)
5
+ */
6
+ export interface TenantUser {
7
+ id: string;
8
+ email: string;
9
+ name: string;
10
+ data: Record<string, any>;
11
+ emailVerified: boolean;
12
+ status: "active" | "suspended" | string;
13
+ createdAt: string;
14
+ }
15
+ /**
16
+ * Resposta de login do tenant
17
+ */
18
+ export interface TenantLoginResponse {
19
+ accessToken: string;
20
+ user: TenantUser;
21
+ }
22
+ /**
23
+ * Credenciais para registro de tenant
24
+ */
25
+ export interface TenantRegisterCredentials {
26
+ email: string;
27
+ password: string;
28
+ name?: string;
29
+ data?: Record<string, any>;
30
+ }
31
+ /**
32
+ * Credenciais para login de tenant
33
+ */
34
+ export interface TenantLoginCredentials {
35
+ email: string;
36
+ password: string;
37
+ }
38
+ /**
39
+ * Módulo de Autenticação de Tenants
40
+ *
41
+ * Permite que usuários finais (clientes) de projetos Aether
42
+ * se registrem, façam login e gerenciem seus perfis.
43
+ *
44
+ * Os dados são isolados por projeto (tabela prj_{id}_users).
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const aether = new PlataformaClient({ ... });
49
+ *
50
+ * // Registrar usuário no projeto
51
+ * const { user, error } = await aether.tenantAuth.signUp('project-id', {
52
+ * email: 'user@example.com',
53
+ * password: '123456',
54
+ * name: 'John Doe',
55
+ * });
56
+ *
57
+ * // Login
58
+ * const { accessToken, user } = await aether.tenantAuth.signIn('project-id', {
59
+ * email: 'user@example.com',
60
+ * password: '123456',
61
+ * });
62
+ *
63
+ * // Obter perfil
64
+ * const profile = await aether.tenantAuth.getProfile('project-id');
65
+ * ```
66
+ */
67
+ export declare class TenantAuthModule {
68
+ private client;
69
+ private http;
70
+ private currentToken;
71
+ private currentUser;
72
+ constructor(client: PlataformaClient, http: AxiosInstance);
73
+ /**
74
+ * Registra um novo usuário tenant no projeto.
75
+ * A tabela de usuários é criada automaticamente se não existir.
76
+ *
77
+ * @param projectId - ID do projeto
78
+ * @param credentials - Email, senha, nome e dados opcionais
79
+ */
80
+ register(projectId: string, credentials: TenantRegisterCredentials): Promise<{
81
+ user: TenantUser;
82
+ message: string;
83
+ }>;
84
+ /**
85
+ * Realiza login de usuário tenant.
86
+ * Armazena o token para uso em requisições subsequentes.
87
+ *
88
+ * @param projectId - ID do projeto
89
+ * @param credentials - Email e senha
90
+ */
91
+ login(projectId: string, credentials: TenantLoginCredentials): Promise<TenantLoginResponse>;
92
+ /**
93
+ * Solicita reset de senha.
94
+ * Retorna mensagem genérica para prevenir enumeração de usuários.
95
+ *
96
+ * @param projectId - ID do projeto
97
+ * @param email - Email do usuário
98
+ */
99
+ forgotPassword(projectId: string, email: string): Promise<{
100
+ message: string;
101
+ }>;
102
+ /**
103
+ * Redefine a senha usando o token recebido por email.
104
+ *
105
+ * @param projectId - ID do projeto
106
+ * @param email - Email do usuário
107
+ * @param token - Token de reset (recebido por email)
108
+ * @param newPassword - Nova senha
109
+ */
110
+ resetPassword(projectId: string, email: string, token: string, newPassword: string): Promise<{
111
+ message: string;
112
+ }>;
113
+ /**
114
+ * Obtém o perfil do usuário autenticado.
115
+ * Requer que login() tenha sido chamado antes.
116
+ *
117
+ * @param projectId - ID do projeto (opcional, usa do token se não fornecido)
118
+ */
119
+ getProfile(projectId?: string): Promise<TenantUser>;
120
+ /**
121
+ * Atualiza o perfil do usuário autenticado.
122
+ *
123
+ * @param projectId - ID do projeto
124
+ * @param updates - Campos a atualizar (name, data)
125
+ */
126
+ updateProfile(projectId: string, updates: {
127
+ name?: string;
128
+ data?: Record<string, any>;
129
+ }): Promise<{
130
+ user: TenantUser;
131
+ message: string;
132
+ }>;
133
+ /**
134
+ * Faz logout do tenant (limpa token local).
135
+ */
136
+ logout(): void;
137
+ /**
138
+ * Alias para register com retorno { user, error }
139
+ */
140
+ signUp(projectId: string, credentials: TenantRegisterCredentials): Promise<{
141
+ user: TenantUser | null;
142
+ error: string | null;
143
+ }>;
144
+ /**
145
+ * Alias para login com retorno { user, accessToken, error }
146
+ */
147
+ signIn(projectId: string, credentials: TenantLoginCredentials): Promise<{
148
+ user: TenantUser | null;
149
+ accessToken: string | null;
150
+ error: string | null;
151
+ }>;
152
+ /**
153
+ * Alias para logout
154
+ */
155
+ signOut(): void;
156
+ /**
157
+ * Retorna o token atual do tenant
158
+ */
159
+ getToken(): string | null;
160
+ /**
161
+ * Define o token do tenant (útil para restaurar sessão)
162
+ */
163
+ setToken(token: string | null): void;
164
+ /**
165
+ * Retorna o usuário atual do tenant
166
+ */
167
+ getCurrentUser(): TenantUser | null;
168
+ /**
169
+ * Verifica se há um usuário autenticado
170
+ */
171
+ isAuthenticated(): boolean;
172
+ }
@@ -0,0 +1,221 @@
1
+ // src/tenant-auth.ts
2
+ // [FEATURE] Módulo de Autenticação de Tenants para SDK
3
+ // Permite autenticação de end-users em projetos Aether
4
+ // Compatible with Firebase Auth-style usage
5
+ // ============================================================================
6
+ // MODULE
7
+ // ============================================================================
8
+ /**
9
+ * Módulo de Autenticação de Tenants
10
+ *
11
+ * Permite que usuários finais (clientes) de projetos Aether
12
+ * se registrem, façam login e gerenciem seus perfis.
13
+ *
14
+ * Os dados são isolados por projeto (tabela prj_{id}_users).
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const aether = new PlataformaClient({ ... });
19
+ *
20
+ * // Registrar usuário no projeto
21
+ * const { user, error } = await aether.tenantAuth.signUp('project-id', {
22
+ * email: 'user@example.com',
23
+ * password: '123456',
24
+ * name: 'John Doe',
25
+ * });
26
+ *
27
+ * // Login
28
+ * const { accessToken, user } = await aether.tenantAuth.signIn('project-id', {
29
+ * email: 'user@example.com',
30
+ * password: '123456',
31
+ * });
32
+ *
33
+ * // Obter perfil
34
+ * const profile = await aether.tenantAuth.getProfile('project-id');
35
+ * ```
36
+ */
37
+ export class TenantAuthModule {
38
+ constructor(client, http) {
39
+ // Armazena o token do tenant atual em memória
40
+ this.currentToken = null;
41
+ this.currentUser = null;
42
+ this.client = client;
43
+ this.http = http;
44
+ }
45
+ // ==========================================================================
46
+ // MÉTODOS PRINCIPAIS
47
+ // ==========================================================================
48
+ /**
49
+ * Registra um novo usuário tenant no projeto.
50
+ * A tabela de usuários é criada automaticamente se não existir.
51
+ *
52
+ * @param projectId - ID do projeto
53
+ * @param credentials - Email, senha, nome e dados opcionais
54
+ */
55
+ async register(projectId, credentials) {
56
+ const { data } = await this.http.post("/auth/tenant/register", {
57
+ projectId,
58
+ ...credentials,
59
+ });
60
+ return data;
61
+ }
62
+ /**
63
+ * Realiza login de usuário tenant.
64
+ * Armazena o token para uso em requisições subsequentes.
65
+ *
66
+ * @param projectId - ID do projeto
67
+ * @param credentials - Email e senha
68
+ */
69
+ async login(projectId, credentials) {
70
+ const { data } = await this.http.post("/auth/tenant/login", {
71
+ projectId,
72
+ ...credentials,
73
+ });
74
+ // Armazena token e usuário
75
+ this.currentToken = data.accessToken;
76
+ this.currentUser = data.user;
77
+ return data;
78
+ }
79
+ /**
80
+ * Solicita reset de senha.
81
+ * Retorna mensagem genérica para prevenir enumeração de usuários.
82
+ *
83
+ * @param projectId - ID do projeto
84
+ * @param email - Email do usuário
85
+ */
86
+ async forgotPassword(projectId, email) {
87
+ const { data } = await this.http.post("/auth/tenant/forgot-password", {
88
+ projectId,
89
+ email,
90
+ });
91
+ return data;
92
+ }
93
+ /**
94
+ * Redefine a senha usando o token recebido por email.
95
+ *
96
+ * @param projectId - ID do projeto
97
+ * @param email - Email do usuário
98
+ * @param token - Token de reset (recebido por email)
99
+ * @param newPassword - Nova senha
100
+ */
101
+ async resetPassword(projectId, email, token, newPassword) {
102
+ const { data } = await this.http.post("/auth/tenant/reset-password", {
103
+ projectId,
104
+ email,
105
+ token,
106
+ newPassword,
107
+ });
108
+ return data;
109
+ }
110
+ /**
111
+ * Obtém o perfil do usuário autenticado.
112
+ * Requer que login() tenha sido chamado antes.
113
+ *
114
+ * @param projectId - ID do projeto (opcional, usa do token se não fornecido)
115
+ */
116
+ async getProfile(projectId) {
117
+ const headers = this.currentToken
118
+ ? { Authorization: `Bearer ${this.currentToken}` }
119
+ : {};
120
+ const { data } = await this.http.get("/auth/tenant/me", { headers });
121
+ this.currentUser = data.user;
122
+ return data.user;
123
+ }
124
+ /**
125
+ * Atualiza o perfil do usuário autenticado.
126
+ *
127
+ * @param projectId - ID do projeto
128
+ * @param updates - Campos a atualizar (name, data)
129
+ */
130
+ async updateProfile(projectId, updates) {
131
+ const headers = this.currentToken
132
+ ? { Authorization: `Bearer ${this.currentToken}` }
133
+ : {};
134
+ const { data } = await this.http.put("/auth/tenant/profile", {
135
+ projectId,
136
+ ...updates,
137
+ }, { headers });
138
+ this.currentUser = data.user;
139
+ return data;
140
+ }
141
+ /**
142
+ * Faz logout do tenant (limpa token local).
143
+ */
144
+ logout() {
145
+ this.currentToken = null;
146
+ this.currentUser = null;
147
+ }
148
+ // ==========================================================================
149
+ // MÉTODOS ESTILO SUPABASE/FIREBASE
150
+ // ==========================================================================
151
+ /**
152
+ * Alias para register com retorno { user, error }
153
+ */
154
+ async signUp(projectId, credentials) {
155
+ try {
156
+ const { user } = await this.register(projectId, credentials);
157
+ return { user, error: null };
158
+ }
159
+ catch (err) {
160
+ const axiosError = err;
161
+ return {
162
+ user: null,
163
+ error: axiosError.response?.data?.error ||
164
+ axiosError.response?.data?.message ||
165
+ err.message,
166
+ };
167
+ }
168
+ }
169
+ /**
170
+ * Alias para login com retorno { user, accessToken, error }
171
+ */
172
+ async signIn(projectId, credentials) {
173
+ try {
174
+ const { user, accessToken } = await this.login(projectId, credentials);
175
+ return { user, accessToken, error: null };
176
+ }
177
+ catch (err) {
178
+ const axiosError = err;
179
+ return {
180
+ user: null,
181
+ accessToken: null,
182
+ error: axiosError.response?.data?.error ||
183
+ axiosError.response?.data?.message ||
184
+ err.message,
185
+ };
186
+ }
187
+ }
188
+ /**
189
+ * Alias para logout
190
+ */
191
+ signOut() {
192
+ this.logout();
193
+ }
194
+ // ==========================================================================
195
+ // ACCESSORS
196
+ // ==========================================================================
197
+ /**
198
+ * Retorna o token atual do tenant
199
+ */
200
+ getToken() {
201
+ return this.currentToken;
202
+ }
203
+ /**
204
+ * Define o token do tenant (útil para restaurar sessão)
205
+ */
206
+ setToken(token) {
207
+ this.currentToken = token;
208
+ }
209
+ /**
210
+ * Retorna o usuário atual do tenant
211
+ */
212
+ getCurrentUser() {
213
+ return this.currentUser;
214
+ }
215
+ /**
216
+ * Verifica se há um usuário autenticado
217
+ */
218
+ isAuthenticated() {
219
+ return this.currentToken !== null;
220
+ }
221
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allanfsouza/aether-sdk",
3
- "version": "2.4.6",
3
+ "version": "2.4.7",
4
4
  "description": "SDK do Cliente para a Plataforma Aether",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -32,4 +32,4 @@
32
32
  "@types/ws": "^8.5.10",
33
33
  "typescript": "^5.3.0"
34
34
  }
35
- }
35
+ }
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import { DatabaseModule } from "./database.js";
6
6
  import { StorageModule } from "./storage.js";
7
7
  import { FunctionsModule } from "./functions.js";
8
8
  import { PushModule } from "./push.js";
9
+ import { TenantAuthModule, TenantUser, TenantLoginResponse, TenantRegisterCredentials, TenantLoginCredentials } from "./tenant-auth.js";
9
10
 
10
11
  // =============================================================================
11
12
  // CONSTANTES DE STORAGE
@@ -51,6 +52,7 @@ export class PlataformaClient {
51
52
  public storage: StorageModule;
52
53
  public functions: FunctionsModule;
53
54
  public push: PushModule;
55
+ public tenantAuth: TenantAuthModule;
54
56
 
55
57
  // Alias para 'db' que o showcase tenta usar como 'database'
56
58
  public database: DatabaseModule;
@@ -90,6 +92,7 @@ export class PlataformaClient {
90
92
  this.storage = new StorageModule(this, this.http);
91
93
  this.functions = new FunctionsModule(this, this.http);
92
94
  this.push = new PushModule(this, this.http);
95
+ this.tenantAuth = new TenantAuthModule(this, this.http);
93
96
 
94
97
  // Cria o alias que o Showcase App espera
95
98
  this.database = this.db;
@@ -241,4 +244,10 @@ export type {
241
244
  PushLogEntry,
242
245
  ListPushLogsOptions,
243
246
  PushStats,
244
- } from "./push.js";
247
+ } from "./push.js";
248
+ export type {
249
+ TenantUser,
250
+ TenantLoginResponse,
251
+ TenantRegisterCredentials,
252
+ TenantLoginCredentials,
253
+ } from "./tenant-auth.js";
@@ -0,0 +1,333 @@
1
+ // src/tenant-auth.ts
2
+ // [FEATURE] Módulo de Autenticação de Tenants para SDK
3
+ // Permite autenticação de end-users em projetos Aether
4
+ // Compatible with Firebase Auth-style usage
5
+
6
+ import type { AxiosInstance, AxiosError } from "axios";
7
+ import type { PlataformaClient } from "./index.js";
8
+
9
+ // ============================================================================
10
+ // TYPES
11
+ // ============================================================================
12
+
13
+ /**
14
+ * Representa um usuário tenant (end-user de um projeto)
15
+ */
16
+ export interface TenantUser {
17
+ id: string;
18
+ email: string;
19
+ name: string;
20
+ data: Record<string, any>;
21
+ emailVerified: boolean;
22
+ status: "active" | "suspended" | string;
23
+ createdAt: string;
24
+ }
25
+
26
+ /**
27
+ * Resposta de login do tenant
28
+ */
29
+ export interface TenantLoginResponse {
30
+ accessToken: string;
31
+ user: TenantUser;
32
+ }
33
+
34
+ /**
35
+ * Credenciais para registro de tenant
36
+ */
37
+ export interface TenantRegisterCredentials {
38
+ email: string;
39
+ password: string;
40
+ name?: string;
41
+ data?: Record<string, any>;
42
+ }
43
+
44
+ /**
45
+ * Credenciais para login de tenant
46
+ */
47
+ export interface TenantLoginCredentials {
48
+ email: string;
49
+ password: string;
50
+ }
51
+
52
+ // ============================================================================
53
+ // MODULE
54
+ // ============================================================================
55
+
56
+ /**
57
+ * Módulo de Autenticação de Tenants
58
+ *
59
+ * Permite que usuários finais (clientes) de projetos Aether
60
+ * se registrem, façam login e gerenciem seus perfis.
61
+ *
62
+ * Os dados são isolados por projeto (tabela prj_{id}_users).
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const aether = new PlataformaClient({ ... });
67
+ *
68
+ * // Registrar usuário no projeto
69
+ * const { user, error } = await aether.tenantAuth.signUp('project-id', {
70
+ * email: 'user@example.com',
71
+ * password: '123456',
72
+ * name: 'John Doe',
73
+ * });
74
+ *
75
+ * // Login
76
+ * const { accessToken, user } = await aether.tenantAuth.signIn('project-id', {
77
+ * email: 'user@example.com',
78
+ * password: '123456',
79
+ * });
80
+ *
81
+ * // Obter perfil
82
+ * const profile = await aether.tenantAuth.getProfile('project-id');
83
+ * ```
84
+ */
85
+ export class TenantAuthModule {
86
+ private client: PlataformaClient;
87
+ private http: AxiosInstance;
88
+
89
+ // Armazena o token do tenant atual em memória
90
+ private currentToken: string | null = null;
91
+ private currentUser: TenantUser | null = null;
92
+
93
+ constructor(client: PlataformaClient, http: AxiosInstance) {
94
+ this.client = client;
95
+ this.http = http;
96
+ }
97
+
98
+ // ==========================================================================
99
+ // MÉTODOS PRINCIPAIS
100
+ // ==========================================================================
101
+
102
+ /**
103
+ * Registra um novo usuário tenant no projeto.
104
+ * A tabela de usuários é criada automaticamente se não existir.
105
+ *
106
+ * @param projectId - ID do projeto
107
+ * @param credentials - Email, senha, nome e dados opcionais
108
+ */
109
+ async register(
110
+ projectId: string,
111
+ credentials: TenantRegisterCredentials
112
+ ): Promise<{ user: TenantUser; message: string }> {
113
+ const { data } = await this.http.post("/auth/tenant/register", {
114
+ projectId,
115
+ ...credentials,
116
+ });
117
+ return data;
118
+ }
119
+
120
+ /**
121
+ * Realiza login de usuário tenant.
122
+ * Armazena o token para uso em requisições subsequentes.
123
+ *
124
+ * @param projectId - ID do projeto
125
+ * @param credentials - Email e senha
126
+ */
127
+ async login(
128
+ projectId: string,
129
+ credentials: TenantLoginCredentials
130
+ ): Promise<TenantLoginResponse> {
131
+ const { data } = await this.http.post<TenantLoginResponse>(
132
+ "/auth/tenant/login",
133
+ {
134
+ projectId,
135
+ ...credentials,
136
+ }
137
+ );
138
+
139
+ // Armazena token e usuário
140
+ this.currentToken = data.accessToken;
141
+ this.currentUser = data.user;
142
+
143
+ return data;
144
+ }
145
+
146
+ /**
147
+ * Solicita reset de senha.
148
+ * Retorna mensagem genérica para prevenir enumeração de usuários.
149
+ *
150
+ * @param projectId - ID do projeto
151
+ * @param email - Email do usuário
152
+ */
153
+ async forgotPassword(
154
+ projectId: string,
155
+ email: string
156
+ ): Promise<{ message: string }> {
157
+ const { data } = await this.http.post("/auth/tenant/forgot-password", {
158
+ projectId,
159
+ email,
160
+ });
161
+ return data;
162
+ }
163
+
164
+ /**
165
+ * Redefine a senha usando o token recebido por email.
166
+ *
167
+ * @param projectId - ID do projeto
168
+ * @param email - Email do usuário
169
+ * @param token - Token de reset (recebido por email)
170
+ * @param newPassword - Nova senha
171
+ */
172
+ async resetPassword(
173
+ projectId: string,
174
+ email: string,
175
+ token: string,
176
+ newPassword: string
177
+ ): Promise<{ message: string }> {
178
+ const { data } = await this.http.post("/auth/tenant/reset-password", {
179
+ projectId,
180
+ email,
181
+ token,
182
+ newPassword,
183
+ });
184
+ return data;
185
+ }
186
+
187
+ /**
188
+ * Obtém o perfil do usuário autenticado.
189
+ * Requer que login() tenha sido chamado antes.
190
+ *
191
+ * @param projectId - ID do projeto (opcional, usa do token se não fornecido)
192
+ */
193
+ async getProfile(projectId?: string): Promise<TenantUser> {
194
+ const headers = this.currentToken
195
+ ? { Authorization: `Bearer ${this.currentToken}` }
196
+ : {};
197
+
198
+ const { data } = await this.http.get<{ user: TenantUser }>(
199
+ "/auth/tenant/me",
200
+ { headers }
201
+ );
202
+
203
+ this.currentUser = data.user;
204
+ return data.user;
205
+ }
206
+
207
+ /**
208
+ * Atualiza o perfil do usuário autenticado.
209
+ *
210
+ * @param projectId - ID do projeto
211
+ * @param updates - Campos a atualizar (name, data)
212
+ */
213
+ async updateProfile(
214
+ projectId: string,
215
+ updates: { name?: string; data?: Record<string, any> }
216
+ ): Promise<{ user: TenantUser; message: string }> {
217
+ const headers = this.currentToken
218
+ ? { Authorization: `Bearer ${this.currentToken}` }
219
+ : {};
220
+
221
+ const { data } = await this.http.put(
222
+ "/auth/tenant/profile",
223
+ {
224
+ projectId,
225
+ ...updates,
226
+ },
227
+ { headers }
228
+ );
229
+
230
+ this.currentUser = data.user;
231
+ return data;
232
+ }
233
+
234
+ /**
235
+ * Faz logout do tenant (limpa token local).
236
+ */
237
+ logout(): void {
238
+ this.currentToken = null;
239
+ this.currentUser = null;
240
+ }
241
+
242
+ // ==========================================================================
243
+ // MÉTODOS ESTILO SUPABASE/FIREBASE
244
+ // ==========================================================================
245
+
246
+ /**
247
+ * Alias para register com retorno { user, error }
248
+ */
249
+ async signUp(
250
+ projectId: string,
251
+ credentials: TenantRegisterCredentials
252
+ ): Promise<{ user: TenantUser | null; error: string | null }> {
253
+ try {
254
+ const { user } = await this.register(projectId, credentials);
255
+ return { user, error: null };
256
+ } catch (err: any) {
257
+ const axiosError = err as AxiosError<{ error?: string; message?: string }>;
258
+ return {
259
+ user: null,
260
+ error:
261
+ axiosError.response?.data?.error ||
262
+ axiosError.response?.data?.message ||
263
+ err.message,
264
+ };
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Alias para login com retorno { user, accessToken, error }
270
+ */
271
+ async signIn(
272
+ projectId: string,
273
+ credentials: TenantLoginCredentials
274
+ ): Promise<{
275
+ user: TenantUser | null;
276
+ accessToken: string | null;
277
+ error: string | null;
278
+ }> {
279
+ try {
280
+ const { user, accessToken } = await this.login(projectId, credentials);
281
+ return { user, accessToken, error: null };
282
+ } catch (err: any) {
283
+ const axiosError = err as AxiosError<{ error?: string; message?: string }>;
284
+ return {
285
+ user: null,
286
+ accessToken: null,
287
+ error:
288
+ axiosError.response?.data?.error ||
289
+ axiosError.response?.data?.message ||
290
+ err.message,
291
+ };
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Alias para logout
297
+ */
298
+ signOut(): void {
299
+ this.logout();
300
+ }
301
+
302
+ // ==========================================================================
303
+ // ACCESSORS
304
+ // ==========================================================================
305
+
306
+ /**
307
+ * Retorna o token atual do tenant
308
+ */
309
+ getToken(): string | null {
310
+ return this.currentToken;
311
+ }
312
+
313
+ /**
314
+ * Define o token do tenant (útil para restaurar sessão)
315
+ */
316
+ setToken(token: string | null): void {
317
+ this.currentToken = token;
318
+ }
319
+
320
+ /**
321
+ * Retorna o usuário atual do tenant
322
+ */
323
+ getCurrentUser(): TenantUser | null {
324
+ return this.currentUser;
325
+ }
326
+
327
+ /**
328
+ * Verifica se há um usuário autenticado
329
+ */
330
+ isAuthenticated(): boolean {
331
+ return this.currentToken !== null;
332
+ }
333
+ }