@bagelink/auth 1.4.169 → 1.4.174

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import { ref } from 'vue';
2
+ import { computed, ref } from 'vue';
3
3
 
4
4
  function createAxiosInstance(baseURL = "") {
5
5
  return axios.create({
@@ -49,74 +49,199 @@ class AuthApi {
49
49
  }
50
50
  setupInterceptors() {
51
51
  this.api.interceptors.request.use((config) => {
52
- const token = localStorage.getItem("access_token");
53
- if (token !== null && config.headers) {
54
- config.headers.Authorization = `Bearer ${token}`;
52
+ const sessionToken = localStorage.getItem("session_token");
53
+ if (sessionToken !== null && config.headers) {
54
+ config.headers.Authorization = `Bearer ${sessionToken}`;
55
55
  }
56
56
  const urlParams = new URLSearchParams(window.location.search);
57
57
  const resetToken = urlParams.get("token");
58
58
  if (resetToken !== null && config.headers) {
59
- config.headers.Authorization = `Bearer ${resetToken}`;
59
+ config.headers["X-Reset-Token"] = resetToken;
60
60
  }
61
61
  return config;
62
62
  });
63
63
  }
64
- async login(username, password) {
65
- const { data } = await this.api.post("/auth/login", {
66
- username: username.toLowerCase(),
64
+ // ============================================
65
+ // Authentication Methods
66
+ // ============================================
67
+ /**
68
+ * Get available authentication methods
69
+ */
70
+ async getAuthMethods() {
71
+ return this.api.get("/authentication/methods");
72
+ }
73
+ /**
74
+ * Register a new account
75
+ */
76
+ async register(data) {
77
+ const response = await this.api.post("/authentication/register", {
78
+ ...data,
79
+ email: data.email.toLowerCase()
80
+ });
81
+ if (response.data.session_token) {
82
+ localStorage.setItem("session_token", response.data.session_token);
83
+ }
84
+ return response;
85
+ }
86
+ /**
87
+ * Login with password
88
+ */
89
+ async login(email, password) {
90
+ const response = await this.api.post("/authentication/login/password", {
91
+ email: email.toLowerCase(),
67
92
  password
68
93
  });
69
- localStorage.setItem("access_token", data.access_token);
70
- return { data };
71
- }
72
- logout() {
73
- localStorage.removeItem("access_token");
74
- window.location.reload();
75
- }
76
- async passwordRecovery(email) {
77
- return this.api.post("/auth/password-recovery", { email });
78
- }
79
- async resetPassword(newPassword) {
80
- return this.api.post("/auth/reset-password", { new_password: newPassword });
81
- }
94
+ if (response.data.session_token) {
95
+ localStorage.setItem("session_token", response.data.session_token);
96
+ }
97
+ return response;
98
+ }
99
+ /**
100
+ * Logout and clear session
101
+ */
102
+ async logout() {
103
+ const response = await this.api.post("/authentication/logout", {});
104
+ localStorage.removeItem("session_token");
105
+ return response;
106
+ }
107
+ /**
108
+ * Refresh current session
109
+ */
110
+ async refreshSession() {
111
+ const response = await this.api.post("/authentication/refresh", {});
112
+ if (response.data.session_token) {
113
+ localStorage.setItem("session_token", response.data.session_token);
114
+ }
115
+ return response;
116
+ }
117
+ // ============================================
118
+ // Current User (Me) Methods
119
+ // ============================================
120
+ /**
121
+ * Get current user account info
122
+ */
82
123
  async getCurrentUser() {
83
- return this.api.get("/users/me");
84
- }
85
- async signup(user) {
86
- return this.api.post("/users/signup", {
87
- email: user.email.toLowerCase(),
88
- password: user.password,
89
- first_name: user.first_name,
90
- last_name: user.last_name
124
+ return this.api.get("/authentication/me");
125
+ }
126
+ /**
127
+ * Update current user profile
128
+ */
129
+ async updateCurrentUser(data) {
130
+ return this.api.patch("/authentication/me", data);
131
+ }
132
+ /**
133
+ * Delete current user account
134
+ */
135
+ async deleteCurrentUser() {
136
+ const response = await this.api.delete("/authentication/me");
137
+ localStorage.removeItem("session_token");
138
+ return response;
139
+ }
140
+ // ============================================
141
+ // Account Management (Admin)
142
+ // ============================================
143
+ /**
144
+ * Get account information by ID
145
+ */
146
+ async getAccount(accountId) {
147
+ return this.api.get(`/authentication/account/${accountId}`);
148
+ }
149
+ /**
150
+ * Update account by ID
151
+ */
152
+ async updateAccount(accountId, data) {
153
+ return this.api.patch(`/authentication/account/${accountId}`, data);
154
+ }
155
+ /**
156
+ * Delete account by ID
157
+ */
158
+ async deleteAccount(accountId) {
159
+ return this.api.delete(`/authentication/account/${accountId}`);
160
+ }
161
+ /**
162
+ * Activate account by ID
163
+ */
164
+ async activateAccount(accountId) {
165
+ return this.api.post(`/authentication/account/${accountId}/activate`, {});
166
+ }
167
+ /**
168
+ * Deactivate account by ID
169
+ */
170
+ async deactivateAccount(accountId) {
171
+ return this.api.post(`/authentication/account/${accountId}/deactivate`, {});
172
+ }
173
+ // ============================================
174
+ // Password Management
175
+ // ============================================
176
+ /**
177
+ * Change password (requires current password)
178
+ */
179
+ async changePassword(data) {
180
+ return this.api.post("/authentication/password/change", data);
181
+ }
182
+ /**
183
+ * Initiate forgot password flow
184
+ */
185
+ async forgotPassword(email) {
186
+ return this.api.post("/authentication/password/forgot", {
187
+ email: email.toLowerCase()
91
188
  });
92
189
  }
93
- async updatePassword(form) {
94
- return this.api.patch("/users/me/password", {
95
- current_password: form.current_password,
96
- new_password: form.new_password
97
- });
98
- }
99
- async updateUserProfile(user) {
100
- return this.api.patch("/users/me", user);
101
- }
102
- async setUserStatus(userId, isActive) {
103
- return this.api.patch(`/users/${userId}`, {
104
- is_active: isActive
190
+ /**
191
+ * Verify password reset token
192
+ */
193
+ async verifyResetToken(token) {
194
+ return this.api.get(`/authentication/password/verify-reset-token/${token}`);
195
+ }
196
+ /**
197
+ * Reset password with token
198
+ */
199
+ async resetPassword(data) {
200
+ return this.api.post("/authentication/password/reset", data);
201
+ }
202
+ // ============================================
203
+ // Email Verification
204
+ // ============================================
205
+ /**
206
+ * Send email verification
207
+ */
208
+ async sendVerification(data = {}, user) {
209
+ return this.api.post("/authentication/verify/send", data, {
210
+ params: user ? { user } : void 0
105
211
  });
106
212
  }
107
- async deleteUser(userId) {
108
- return this.api.delete(`/users/${userId}`);
109
- }
110
- async getUsers(limit = 100, skip) {
111
- return this.api.get("/users/", {
112
- params: { skip, limit }
113
- });
114
- }
115
- async createUser(user) {
116
- return this.api.post("/users/", user);
117
- }
118
- async getUser(userId) {
119
- return this.api.get(`/users/${userId}`);
213
+ /**
214
+ * Verify email with token
215
+ */
216
+ async verifyEmail(token) {
217
+ return this.api.post("/authentication/verify/email", { token });
218
+ }
219
+ // ============================================
220
+ // Session Management
221
+ // ============================================
222
+ /**
223
+ * Get sessions for an account
224
+ */
225
+ async getSessions(accountId) {
226
+ return this.api.get(`/authentication/sessions/${accountId}`);
227
+ }
228
+ /**
229
+ * Revoke a specific session
230
+ */
231
+ async revokeSession(sessionToken) {
232
+ return this.api.delete(`/authentication/sessions/${sessionToken}`);
233
+ }
234
+ /**
235
+ * Revoke all sessions for an account
236
+ */
237
+ async revokeAllSessions(accountId) {
238
+ return this.api.delete(`/authentication/sessions/account/${accountId}`);
239
+ }
240
+ /**
241
+ * Cleanup expired sessions (admin)
242
+ */
243
+ async cleanupSessions() {
244
+ return this.api.post("/authentication/cleanup-sessions", {});
120
245
  }
121
246
  }
122
247
 
@@ -125,41 +250,85 @@ var AuthState = /* @__PURE__ */ ((AuthState2) => {
125
250
  AuthState2["LOGOUT"] = "logout";
126
251
  AuthState2["SIGNUP"] = "signup";
127
252
  AuthState2["PASSWORD_RESET"] = "password_reset";
253
+ AuthState2["PASSWORD_CHANGE"] = "password_change";
128
254
  AuthState2["PROFILE_UPDATE"] = "profile_update";
129
255
  AuthState2["AUTH_CHECK"] = "auth_check";
256
+ AuthState2["EMAIL_VERIFIED"] = "email_verified";
257
+ AuthState2["SESSION_REFRESH"] = "session_refresh";
130
258
  return AuthState2;
131
259
  })(AuthState || {});
260
+ function accountToUser(account) {
261
+ if (account === null) return null;
262
+ if (account.person !== void 0) {
263
+ return {
264
+ id: account.person.id,
265
+ accountId: account.id,
266
+ name: account.person.name,
267
+ email: account.person.email,
268
+ type: account.account_type,
269
+ roles: account.person.roles,
270
+ isActive: account.is_active,
271
+ isVerified: account.is_verified,
272
+ lastLogin: account.last_login
273
+ };
274
+ }
275
+ if (account.entity !== void 0) {
276
+ return {
277
+ id: account.entity.id,
278
+ accountId: account.id,
279
+ name: account.entity.name,
280
+ type: account.account_type,
281
+ isActive: account.is_active,
282
+ isVerified: account.is_verified,
283
+ lastLogin: account.last_login,
284
+ entityType: account.entity.type,
285
+ metadata: account.entity.metadata
286
+ };
287
+ }
288
+ const emailMethod = account.authentication_methods?.find(
289
+ (m) => m.type === "password" || m.type === "email_token"
290
+ );
291
+ return {
292
+ id: account.id,
293
+ accountId: account.id,
294
+ name: account.display_name,
295
+ email: emailMethod?.identifier,
296
+ type: account.account_type,
297
+ isActive: account.is_active,
298
+ isVerified: account.is_verified,
299
+ lastLogin: account.last_login
300
+ };
301
+ }
132
302
 
133
303
  let authApi = null;
134
304
  let eventEmitter = null;
135
- const currentUser = ref({
136
- id: "",
137
- email: "",
138
- first_name: "",
139
- last_name: "",
140
- is_superuser: false,
141
- is_active: false
142
- });
305
+ const accountInfo = ref(null);
143
306
  function initAuth({
144
307
  axios,
145
308
  baseURL
146
309
  }) {
147
- if (!authApi) {
310
+ if (authApi === null) {
148
311
  authApi = new AuthApi(axios, baseURL);
149
312
  }
150
- if (!eventEmitter) {
313
+ if (eventEmitter === null) {
151
314
  eventEmitter = new EventEmitter();
152
315
  }
153
316
  return {
154
317
  // Event listener methods
155
318
  on(event, handler) {
156
- eventEmitter.on(event, handler);
319
+ if (eventEmitter) {
320
+ eventEmitter.on(event, handler);
321
+ }
157
322
  },
158
323
  off(event, handler) {
159
- eventEmitter.off(event, handler);
324
+ if (eventEmitter) {
325
+ eventEmitter.off(event, handler);
326
+ }
160
327
  },
161
328
  removeAllListeners(event) {
162
- eventEmitter.removeAllListeners(event);
329
+ if (eventEmitter) {
330
+ eventEmitter.removeAllListeners(event);
331
+ }
163
332
  },
164
333
  install(app) {
165
334
  app.config.globalProperties.$auth = useAuth();
@@ -167,132 +336,191 @@ function initAuth({
167
336
  };
168
337
  }
169
338
  function useAuth() {
170
- if (!authApi) {
339
+ if (authApi === null) {
171
340
  throw new Error("Auth not initialized. Call initAuth first.");
172
341
  }
173
- const getFullName = () => `${currentUser.value.first_name} ${currentUser.value.last_name}`;
174
- const getIsLoggedIn = () => currentUser.value.id.length > 0;
342
+ if (eventEmitter === null) {
343
+ throw new Error("Event emitter not initialized. Call initAuth first.");
344
+ }
345
+ const api = authApi;
346
+ const emitter = eventEmitter;
347
+ const user = computed(() => accountToUser(accountInfo.value));
348
+ const getFullName = () => {
349
+ return user.value?.name ?? "";
350
+ };
351
+ const getIsLoggedIn = () => {
352
+ return user.value !== null;
353
+ };
354
+ const getEmail = () => {
355
+ return user.value?.email ?? "";
356
+ };
357
+ const getRoles = () => {
358
+ return user.value?.roles ?? [];
359
+ };
360
+ const getAccountType = () => {
361
+ return user.value?.type ?? "person";
362
+ };
363
+ const isPersonAccount = () => {
364
+ return user.value?.type === "person";
365
+ };
366
+ const isEntityAccount = () => {
367
+ return user.value?.type === "entity";
368
+ };
175
369
  async function logout() {
176
- try {
177
- await authApi.logout();
178
- currentUser.value = {
179
- id: "",
180
- email: "",
181
- first_name: "",
182
- last_name: "",
183
- is_superuser: false,
184
- is_active: false
185
- };
186
- eventEmitter.emit(AuthState.LOGOUT);
187
- } catch (error) {
188
- throw error;
189
- }
370
+ const logoutPromise = api.logout();
371
+ await logoutPromise.catch(() => {
372
+ });
373
+ accountInfo.value = null;
374
+ emitter.emit(AuthState.LOGOUT);
190
375
  }
191
376
  async function login(credentials) {
192
- try {
193
- await authApi.login(
194
- credentials.email.toLowerCase(),
195
- credentials.password
196
- );
377
+ const { data } = await api.login(
378
+ credentials.email.toLowerCase(),
379
+ credentials.password
380
+ );
381
+ if (data.success === true && data.requires_verification !== true) {
197
382
  await checkAuth();
198
- eventEmitter.emit(AuthState.LOGIN);
199
- } catch (error) {
200
- throw error;
201
383
  }
384
+ emitter.emit(AuthState.LOGIN);
385
+ return data;
202
386
  }
203
387
  async function checkAuth() {
204
388
  try {
205
- if (!getIsLoggedIn()) {
206
- const { data } = await authApi.getCurrentUser();
207
- currentUser.value = data;
208
- if (getIsLoggedIn()) {
209
- eventEmitter.emit(AuthState.AUTH_CHECK);
210
- }
389
+ const { data } = await api.getCurrentUser();
390
+ accountInfo.value = data;
391
+ if (getIsLoggedIn()) {
392
+ emitter.emit(AuthState.AUTH_CHECK);
211
393
  }
212
- } catch (error) {
394
+ return true;
395
+ } catch {
396
+ accountInfo.value = null;
213
397
  return false;
214
398
  }
215
- return getIsLoggedIn();
216
399
  }
217
- async function signup(user) {
218
- try {
219
- if (user.password !== user.confirmPassword) {
220
- throw new Error("Passwords do not match");
221
- }
222
- const { data } = await authApi.signup(user);
223
- currentUser.value = data;
224
- eventEmitter.emit(AuthState.SIGNUP);
225
- } catch (error) {
226
- throw error;
400
+ async function signup(newUser) {
401
+ const hasPassword = newUser.password !== void 0 && newUser.password.length > 0;
402
+ if (hasPassword && newUser.password !== newUser.confirmPassword) {
403
+ throw new Error("Passwords do not match");
227
404
  }
228
- }
229
- async function recoverPassword(email) {
230
- try {
231
- await authApi.passwordRecovery(email);
232
- } catch (error) {
233
- throw error;
405
+ const { data } = await api.register({
406
+ email: newUser.email,
407
+ first_name: newUser.first_name,
408
+ last_name: newUser.last_name,
409
+ phone_number: newUser.phone_number,
410
+ password: newUser.password
411
+ });
412
+ if (data.success === true && data.requires_verification !== true) {
413
+ await checkAuth();
234
414
  }
415
+ emitter.emit(AuthState.SIGNUP);
416
+ return data;
235
417
  }
236
- async function resetPassword(newPassword) {
237
- try {
238
- await authApi.resetPassword(newPassword);
239
- eventEmitter.emit(AuthState.PASSWORD_RESET);
240
- } catch (error) {
241
- throw error;
242
- }
418
+ async function forgotPassword(email) {
419
+ await api.forgotPassword(email);
243
420
  }
244
- async function updatePassword(form) {
245
- try {
246
- if (form.new_password !== form.confirmNewPassword) {
247
- throw new Error("Passwords do not match");
248
- }
249
- await authApi.updatePassword(form);
250
- eventEmitter.emit(AuthState.PASSWORD_RESET);
251
- } catch (error) {
252
- throw error;
253
- }
421
+ async function verifyResetToken(token) {
422
+ await api.verifyResetToken(token);
254
423
  }
255
- async function updateProfile(user) {
256
- try {
257
- const { data } = await authApi.updateUserProfile(user);
258
- currentUser.value = { ...currentUser.value, ...data };
259
- eventEmitter.emit(AuthState.PROFILE_UPDATE);
260
- } catch (error) {
261
- throw error;
424
+ async function resetPassword(token, newPassword) {
425
+ await api.resetPassword({ token, new_password: newPassword });
426
+ emitter.emit(AuthState.PASSWORD_RESET);
427
+ }
428
+ async function changePassword(form) {
429
+ if (form.new_password !== form.confirmNewPassword) {
430
+ throw new Error("Passwords do not match");
262
431
  }
432
+ await api.changePassword({
433
+ current_password: form.current_password,
434
+ new_password: form.new_password
435
+ });
436
+ emitter.emit(AuthState.PASSWORD_CHANGE);
263
437
  }
264
- async function toggleUserStatus(userId, isActive) {
265
- try {
266
- await authApi.setUserStatus(userId, isActive);
267
- } catch (error) {
268
- throw error;
438
+ async function updateProfile(updates) {
439
+ const { data } = await api.updateCurrentUser(updates);
440
+ accountInfo.value = data;
441
+ emitter.emit(AuthState.PROFILE_UPDATE);
442
+ }
443
+ async function activateAccount(accountId) {
444
+ await api.activateAccount(accountId);
445
+ }
446
+ async function deactivateAccount(accountId) {
447
+ await api.deactivateAccount(accountId);
448
+ }
449
+ async function deleteAccount(accountId) {
450
+ await api.deleteAccount(accountId);
451
+ }
452
+ async function deleteCurrentUser() {
453
+ await api.deleteCurrentUser();
454
+ accountInfo.value = null;
455
+ }
456
+ async function sendVerification(email) {
457
+ await api.sendVerification({ email });
458
+ }
459
+ async function verifyEmail(token) {
460
+ await api.verifyEmail(token);
461
+ await checkAuth();
462
+ emitter.emit(AuthState.EMAIL_VERIFIED);
463
+ }
464
+ async function refreshSession() {
465
+ await api.refreshSession();
466
+ emitter.emit(AuthState.SESSION_REFRESH);
467
+ }
468
+ async function getSessions(accountId) {
469
+ const id = accountId ?? user.value?.accountId;
470
+ if (id === void 0 || id === "") {
471
+ throw new Error("No account ID available");
269
472
  }
473
+ return api.getSessions(id);
270
474
  }
271
- async function deleteUser(userId) {
272
- try {
273
- await authApi.deleteUser(userId);
274
- } catch (error) {
275
- throw error;
475
+ async function revokeSession(sessionToken) {
476
+ await api.revokeSession(sessionToken);
477
+ }
478
+ async function revokeAllSessions(accountId) {
479
+ const id = accountId ?? user.value?.accountId;
480
+ if (id === void 0 || id === "") {
481
+ throw new Error("No account ID available");
276
482
  }
483
+ await api.revokeAllSessions(id);
277
484
  }
278
485
  return {
279
- // State
280
- currentUser,
486
+ // Primary State (use this!)
487
+ user,
488
+ // Full account info (for advanced use cases)
489
+ accountInfo,
281
490
  // Getters
282
491
  getFullName,
283
492
  getIsLoggedIn,
284
- // Actions
285
- logout,
493
+ getEmail,
494
+ getRoles,
495
+ getAccountType,
496
+ isPersonAccount,
497
+ isEntityAccount,
498
+ // Authentication Actions
286
499
  login,
287
- checkAuth,
500
+ logout,
288
501
  signup,
289
- recoverPassword,
290
- resetPassword,
291
- updatePassword,
502
+ checkAuth,
503
+ refreshSession,
504
+ // Profile Actions
292
505
  updateProfile,
293
- toggleUserStatus,
294
- deleteUser
506
+ deleteCurrentUser,
507
+ // Password Actions
508
+ changePassword,
509
+ forgotPassword,
510
+ verifyResetToken,
511
+ resetPassword,
512
+ // Email Verification Actions
513
+ sendVerification,
514
+ verifyEmail,
515
+ // Admin Actions
516
+ activateAccount,
517
+ deactivateAccount,
518
+ deleteAccount,
519
+ // Session Management
520
+ getSessions,
521
+ revokeSession,
522
+ revokeAllSessions
295
523
  };
296
524
  }
297
525
 
298
- export { AuthApi, AuthState, initAuth, useAuth };
526
+ export { AuthApi, AuthState, accountToUser, initAuth, useAuth };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/auth",
3
3
  "type": "module",
4
- "version": "1.4.169",
4
+ "version": "1.4.174",
5
5
  "description": "Bagelink auth package",
6
6
  "author": {
7
7
  "name": "Bagel Studio",