ngx-better-auth 0.6.0 → 0.7.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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  ![angular](https://img.shields.io/badge/angular-20+-dd0031?logo=angular&logoColor=white)
9
9
  ![better-auth](https://img.shields.io/badge/better--auth-1.3.7+-blueviolet)
10
10
 
11
- An **Angular 20+ integration for [Better Auth](https://github.com/better-auth/better-auth)**.
11
+ An **Angular 20+ wrapper for [Better Auth](https://github.com/better-auth/better-auth)**.
12
12
  Provides reactive session handling with **signals**, clean **DI provider setup** with **observables**, and modern **guards**.
13
13
 
14
14
  ---
@@ -49,7 +49,9 @@ export const appConfig: ApplicationConfig = {
49
49
 
50
50
  ## 🧩 Different services
51
51
 
52
- You can inject different services depending on your needs:
52
+ You can inject different services depending on your needs.
53
+ **AuthService** provides the core Better Auth client methods (login, logout, register, e.g.).
54
+ The full list of methods is available at the end of this README.
53
55
 
54
56
  ### Global services
55
57
  - `AuthService`
@@ -58,6 +60,7 @@ You can inject different services depending on your needs:
58
60
 
59
61
  ### Plugin services
60
62
  Authentication:
63
+ - `UsernameService`
61
64
  - `TwoFactorService`
62
65
  - `PasskeyService`
63
66
  - `GenericOauthService`
@@ -108,7 +111,7 @@ This library ships with guards to quickly set up route protection.
108
111
  ### Usage in routes
109
112
  ```ts
110
113
  import { Routes } from '@angular/router'
111
- import { canActivate, redirectLoggedInTo, redirectUnauthorizedTo, hasRole } from 'ngx-better-auth/guards'
114
+ import { canActivate, redirectLoggedInTo, redirectUnauthorizedTo, hasRole } from 'ngx-better-auth'
112
115
 
113
116
  export const routes: Routes = [
114
117
  {
@@ -127,4 +130,9 @@ export const routes: Routes = [
127
130
  ...canActivate(redirectLoggedInTo(['/']))
128
131
  }
129
132
  ]
130
- ```
133
+ ```
134
+
135
+ ## 📋 Full list of AuthService methods
136
+
137
+ ### AuthService
138
+
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, Injectable, signal, computed, InjectionToken, makeEnvironmentProviders } from '@angular/core';
3
- import { Observable, filter, map, shareReplay, defer, switchMap, tap } from 'rxjs';
3
+ import { Observable, filter, map, shareReplay, defer, switchMap } from 'rxjs';
4
4
  import { createAuthClient } from 'better-auth/client';
5
5
  import { Router } from '@angular/router';
6
6
 
@@ -25,11 +25,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
25
25
  }]
26
26
  }] });
27
27
 
28
- function isEmail(email) {
29
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
30
- return emailRegex.test(email);
31
- }
32
-
33
28
  class AuthService {
34
29
  mainService = inject(MainService);
35
30
  client = this.mainService.authClient;
@@ -83,24 +78,9 @@ class AuthService {
83
78
  this.session.set(session.data);
84
79
  });
85
80
  }
86
- /**
87
- * pass either email or username to sign in. Needs username plugin enabled to use username.
88
- * @param data : { email?: string; username?: string; password: string; rememberMe?: boolean }
89
- */
90
- signIn(data) {
91
- if (isEmail(data.login)) {
92
- return this.signInEmail({ email: data.login, password: data.password, rememberMe: data.rememberMe });
93
- }
94
- else {
95
- return this.signInUsername({ username: data.login, password: data.password, rememberMe: data.rememberMe });
96
- }
97
- }
98
81
  signInEmail(data) {
99
82
  return defer(() => this.client.signIn.email(data)).pipe(switchMap(() => this.sessionState$.pipe(filter((s) => s !== null))));
100
83
  }
101
- signInUsername(data) {
102
- return defer(() => this.client.signIn.username(data)).pipe(switchMap(() => this.sessionState$.pipe(filter((s) => s !== null))));
103
- }
104
84
  /**
105
85
  * Sign up a new user using email and password.
106
86
  *
@@ -117,28 +97,25 @@ class AuthService {
117
97
  return defer(() => this.client.signOut()).pipe(switchMap(() => this.sessionState$.pipe(filter((s) => s === null))));
118
98
  }
119
99
  sendVerificationEmail(data) {
120
- return defer(() => this.client.sendVerificationEmail(data));
100
+ return defer(() => this.client.sendVerificationEmail(data)).pipe(map((data) => this.mainService.mapData(data)));
121
101
  }
122
102
  requestPasswordReset(data) {
123
- return defer(() => this.client.requestPasswordReset(data));
103
+ return defer(() => this.client.requestPasswordReset(data)).pipe(map((data) => this.mainService.mapData(data)));
124
104
  }
125
105
  resetPassword(data) {
126
- return defer(() => this.client.resetPassword(data));
106
+ return defer(() => this.client.resetPassword(data)).pipe(map((data) => this.mainService.mapData(data)));
127
107
  }
128
108
  changePassword(data) {
129
- return defer(() => this.client.changePassword(data));
109
+ return defer(() => this.client.changePassword(data)).pipe(map((data) => this.mainService.mapData(data)));
130
110
  }
131
111
  changeEmail(data) {
132
- return defer(() => this.client.changeEmail(data));
112
+ return defer(() => this.client.changeEmail(data)).pipe(map((data) => this.mainService.mapData(data)));
133
113
  }
134
114
  updateUser(data) {
135
- return defer(() => this.client.updateUser(data));
136
- }
137
- isUsernameAvailable(data) {
138
- return defer(() => this.client.isUsernameAvailable(data));
115
+ return defer(() => this.client.updateUser(data)).pipe(map((data) => this.mainService.mapData(data)));
139
116
  }
140
117
  deleteUser(data) {
141
- return defer(() => this.client.deleteUser(data)).pipe(tap(() => this.sessionState$.pipe(filter((s) => s === null))));
118
+ return defer(() => this.client.deleteUser(data)).pipe(switchMap(() => this.sessionState$.pipe(filter((s) => s === null))));
142
119
  }
143
120
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
144
121
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AuthService, providedIn: 'root' });
@@ -156,8 +133,8 @@ class SessionService {
156
133
  listSessions() {
157
134
  return defer(() => this.client.listSessions()).pipe(map((data) => this.mainService.mapData(data)));
158
135
  }
159
- revokeSession(sessionToken) {
160
- return defer(() => this.client.revokeSession({ token: sessionToken })).pipe(map((data) => this.mainService.mapData(data)));
136
+ revokeSession(data) {
137
+ return defer(() => this.client.revokeSession(data)).pipe(map((data) => this.mainService.mapData(data)));
161
138
  }
162
139
  revokeOtherSessions() {
163
140
  return defer(() => this.client.revokeOtherSessions()).pipe(map((data) => this.mainService.mapData(data)));
@@ -211,28 +188,28 @@ class TwoFactorService {
211
188
  this.twoFactor = client.twoFactor;
212
189
  }
213
190
  enable(data) {
214
- return defer(() => this.twoFactor.enable(data));
191
+ return defer(() => this.twoFactor.enable(data)).pipe(map((data) => this.mainService.mapData(data)));
215
192
  }
216
193
  disable(data) {
217
- return defer(() => this.twoFactor.disable(data));
194
+ return defer(() => this.twoFactor.disable(data)).pipe(map((data) => this.mainService.mapData(data)));
218
195
  }
219
196
  getTotpUri(data) {
220
- return defer(() => this.twoFactor.getTotpUri(data));
197
+ return defer(() => this.twoFactor.getTotpUri(data)).pipe(map((data) => this.mainService.mapData(data)));
221
198
  }
222
199
  verifyTotp(data) {
223
- return defer(() => this.twoFactor.verifyTotp(data));
200
+ return defer(() => this.twoFactor.verifyTotp(data)).pipe(map((data) => this.mainService.mapData(data)));
224
201
  }
225
- sendOtp(data) {
226
- return defer(() => this.twoFactor.sendOtp(data));
202
+ sendOtp() {
203
+ return defer(() => this.twoFactor.sendOtp()).pipe(map((data) => this.mainService.mapData(data)));
227
204
  }
228
205
  verifyOtp(data) {
229
- return defer(() => this.twoFactor.verifyOtp(data));
206
+ return defer(() => this.twoFactor.verifyOtp(data)).pipe(map((data) => this.mainService.mapData(data)));
230
207
  }
231
208
  generateBackupCodes(data) {
232
- return defer(() => this.twoFactor.generateBackupCodes(data));
209
+ return defer(() => this.twoFactor.generateBackupCodes(data)).pipe(map((data) => this.mainService.mapData(data)));
233
210
  }
234
211
  verifyBackupCode(data) {
235
- return defer(() => this.twoFactor.verifyBackupCode(data));
212
+ return defer(() => this.twoFactor.verifyBackupCode(data)).pipe(map((data) => this.mainService.mapData(data)));
236
213
  }
237
214
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TwoFactorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
238
215
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TwoFactorService, providedIn: 'root' });
@@ -251,16 +228,19 @@ class PasskeyService {
251
228
  this.passkey = client.passkey;
252
229
  }
253
230
  addPasskey(data) {
254
- return defer(() => this.passkey.addPasskey(data));
231
+ return defer(() => this.passkey.addPasskey(data)).pipe(map((data) => this.mainService.mapData(data)));
232
+ }
233
+ signIn(data) {
234
+ return defer(() => this.mainService.authClient.signIn.passkey(data));
255
235
  }
256
236
  listUserPasskeys() {
257
- return defer(() => this.passkey.listUserPasskeys());
237
+ return defer(() => this.passkey.listUserPasskeys()).pipe(map((data) => this.mainService.mapData(data)));
258
238
  }
259
239
  deletePasskey(data) {
260
- return defer(() => this.passkey.deletePasskey(data));
240
+ return defer(() => this.passkey.deletePasskey(data)).pipe(map((data) => this.mainService.mapData(data)));
261
241
  }
262
242
  updatePasskey(data) {
263
- return defer(() => this.passkey.updatePasskey(data));
243
+ return defer(() => this.passkey.updatePasskey(data)).pipe(map((data) => this.mainService.mapData(data)));
264
244
  }
265
245
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PasskeyService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
266
246
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: PasskeyService, providedIn: 'root' });
@@ -366,6 +346,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImpor
366
346
  args: [{ providedIn: 'root' }]
367
347
  }], ctorParameters: () => [] });
368
348
 
349
+ function isEmail(email) {
350
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
351
+ return emailRegex.test(email);
352
+ }
353
+
354
+ class UsernameService {
355
+ mainService = inject(MainService);
356
+ authService = inject(AuthService);
357
+ username = this.mainService.authClient;
358
+ /**
359
+ * pass either email or username to sign in. Needs username plugin enabled to use username.
360
+ * @param data : { email?: string; username?: string; password: string; rememberMe?: boolean }
361
+ */
362
+ signIn(data) {
363
+ if (isEmail(data.login)) {
364
+ return this.authService.signInEmail({ email: data.login, password: data.password, rememberMe: data.rememberMe });
365
+ }
366
+ else {
367
+ return this.signInUsername({ username: data.login, password: data.password, rememberMe: data.rememberMe });
368
+ }
369
+ }
370
+ signInUsername(data) {
371
+ return defer(() => this.username.signIn.username(data)).pipe(switchMap(() => this.authService.sessionState$.pipe(filter((s) => s !== null))));
372
+ }
373
+ isUsernameAvailable(data) {
374
+ return defer(() => this.username.isUsernameAvailable(data));
375
+ }
376
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: UsernameService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
377
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: UsernameService, providedIn: 'root' });
378
+ }
379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: UsernameService, decorators: [{
380
+ type: Injectable,
381
+ args: [{ providedIn: 'root' }]
382
+ }] });
383
+
369
384
  class AdminService {
370
385
  mainService = inject(MainService);
371
386
  admin;
@@ -375,40 +390,49 @@ class AdminService {
375
390
  this.admin = client.admin;
376
391
  }
377
392
  setRole(data) {
378
- return defer(() => this.admin.setRole(data));
393
+ return defer(() => this.admin.setRole(data)).pipe(map((data) => this.mainService.mapData(data)));
379
394
  }
380
- setUserPassword(data) {
381
- return defer(() => this.admin.setUserPassword(data));
395
+ createUser(data) {
396
+ return defer(() => this.admin.createUser(data)).pipe(map((data) => this.mainService.mapData(data)));
382
397
  }
383
- banUser(data) {
384
- return defer(() => this.admin.banUser(data));
398
+ updateUser(data) {
399
+ return defer(() => this.admin.updateUser(data)).pipe(map((data) => this.mainService.mapData(data)));
385
400
  }
386
- unbanUser(data) {
387
- return defer(() => this.admin.unbanUser(data));
401
+ listUsers(data) {
402
+ return defer(() => this.admin.listUsers(data)).pipe(map((data) => this.mainService.mapData(data)));
388
403
  }
389
404
  listUserSessions(data) {
390
- return defer(() => this.admin.listUserSessions(data));
405
+ return defer(() => this.admin.listUserSessions(data)).pipe(map((data) => this.mainService.mapData(data)));
391
406
  }
392
- revokeUserSession(data) {
393
- return defer(() => this.admin.revokeUserSession(data));
407
+ unbanUser(data) {
408
+ return defer(() => this.admin.unbanUser(data)).pipe(map((data) => this.mainService.mapData(data)));
394
409
  }
395
- revokeUserSessions(data) {
396
- return defer(() => this.admin.revokeUserSessions(data));
410
+ banUser(data) {
411
+ return defer(() => this.admin.banUser(data)).pipe(map((data) => this.mainService.mapData(data)));
397
412
  }
398
413
  impersonateUser(data) {
399
- return defer(() => this.admin.impersonateUser(data));
414
+ return defer(() => this.admin.impersonateUser(data)).pipe(map((data) => this.mainService.mapData(data)));
400
415
  }
401
416
  stopImpersonating() {
402
417
  return defer(() => this.admin.stopImpersonating());
403
418
  }
419
+ revokeUserSession(data) {
420
+ return defer(() => this.admin.revokeUserSession(data)).pipe(map((data) => this.mainService.mapData(data)));
421
+ }
422
+ revokeUserSessions(data) {
423
+ return defer(() => this.admin.revokeUserSessions(data)).pipe(map((data) => this.mainService.mapData(data)));
424
+ }
404
425
  removeUser(data) {
405
- return defer(() => this.admin.removeUser(data));
426
+ return defer(() => this.admin.removeUser(data)).pipe(map((data) => this.mainService.mapData(data)));
427
+ }
428
+ setUserPassword(data) {
429
+ return defer(() => this.admin.setUserPassword(data)).pipe(map((data) => this.mainService.mapData(data)));
406
430
  }
407
431
  hasPermission(data) {
408
432
  return defer(() => this.admin.hasPermission(data));
409
433
  }
410
434
  checkRolePermission(data) {
411
- return this.admin.checkRolePermission(data);
435
+ return defer(() => this.admin.checkRolePermission(data));
412
436
  }
413
437
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
414
438
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AdminService, providedIn: 'root' });
@@ -426,62 +450,62 @@ class OrganizationService {
426
450
  validatePlugin(client, 'organization');
427
451
  this.organization = client.organization;
428
452
  }
429
- createOrganization(data) {
430
- return defer(() => this.organization.create(data));
453
+ create(data) {
454
+ return defer(() => this.organization.create(data)).pipe(map((data) => this.mainService.mapData(data)));
431
455
  }
432
456
  checkSlug(data) {
433
457
  return defer(() => this.organization.checkSlug(data));
434
458
  }
435
459
  list() {
436
- return defer(() => this.organization.list());
460
+ return defer(() => this.organization.list()).pipe(map((data) => this.mainService.mapData(data)));
437
461
  }
438
462
  setActive(data) {
439
- return defer(() => this.organization.setActive(data));
463
+ return defer(() => this.organization.setActive(data)).pipe(map((data) => this.mainService.mapData(data)));
440
464
  }
441
465
  getFullOrganization(data) {
442
- return defer(() => this.organization.getFullOrganization(data));
466
+ return defer(() => this.organization.getFullOrganization(data)).pipe(map((data) => this.mainService.mapData(data)));
443
467
  }
444
468
  update(data) {
445
- return defer(() => this.organization.update(data));
469
+ return defer(() => this.organization.update(data)).pipe(map((data) => this.mainService.mapData(data)));
446
470
  }
447
471
  delete(data) {
448
- return defer(() => this.organization.delete(data));
472
+ return defer(() => this.organization.delete(data)).pipe(map((data) => this.mainService.mapData(data)));
449
473
  }
450
474
  inviteMember(data) {
451
- return defer(() => this.organization.inviteMember(data));
475
+ return defer(() => this.organization.inviteMember(data)).pipe(map((data) => this.mainService.mapData(data)));
452
476
  }
453
477
  acceptInvitation(data) {
454
- return defer(() => this.organization.acceptInvitation(data));
478
+ return defer(() => this.organization.acceptInvitation(data)).pipe(map((data) => this.mainService.mapData(data)));
455
479
  }
456
480
  cancelInvitation(data) {
457
- return defer(() => this.organization.cancelInvitation(data));
481
+ return defer(() => this.organization.cancelInvitation(data)).pipe(map((data) => this.mainService.mapData(data)));
458
482
  }
459
483
  rejectInvitation(data) {
460
- return defer(() => this.organization.rejectInvitation(data));
484
+ return defer(() => this.organization.rejectInvitation(data)).pipe(map((data) => this.mainService.mapData(data)));
461
485
  }
462
486
  getInvitation(data) {
463
- return defer(() => this.organization.getInvitation(data));
487
+ return defer(() => this.organization.getInvitation(data)).pipe(map((data) => this.mainService.mapData(data)));
464
488
  }
465
489
  listInvitations(data) {
466
- return defer(() => this.organization.listInvitations(data));
490
+ return defer(() => this.organization.listInvitations(data)).pipe(map((data) => this.mainService.mapData(data)));
467
491
  }
468
492
  listUserInvitations() {
469
- return defer(() => this.organization.listUserInvitations());
493
+ return defer(() => this.organization.listUserInvitations()).pipe(map((data) => this.mainService.mapData(data)));
470
494
  }
471
495
  listMembers(data = {}) {
472
496
  return defer(() => this.organization.listMembers(data));
473
497
  }
474
498
  removeMember(data) {
475
- return defer(() => this.organization.removeMember(data));
499
+ return defer(() => this.organization.removeMember(data)).pipe(map((data) => this.mainService.mapData(data)));
476
500
  }
477
501
  updateMemberRoles(data) {
478
502
  return defer(() => this.organization.updateMemberRoles(data));
479
503
  }
480
504
  getActiveMember() {
481
- return defer(() => this.organization.getActiveMember());
505
+ return defer(() => this.organization.getActiveMember()).pipe(map((data) => this.mainService.mapData(data)));
482
506
  }
483
507
  leave(data) {
484
- return defer(() => this.organization.leave(data));
508
+ return defer(() => this.organization.leave(data)).pipe(map((data) => this.mainService.mapData(data)));
485
509
  }
486
510
  createTeam(data) {
487
511
  return defer(() => this.organization.createTeam(data));
@@ -561,7 +585,7 @@ function hasRole(requiredRoles, redirectTo = ['/unauthorized']) {
561
585
  if (!session || !session.user) {
562
586
  return router.createUrlTree(redirectTo);
563
587
  }
564
- const role = session?.user?.role;
588
+ const role = session?.user?.['role'];
565
589
  if (Array.isArray(role)) {
566
590
  if (role.some((r) => requiredRoles.includes(r))) {
567
591
  return true;
@@ -587,5 +611,5 @@ function canActivate(pipe) {
587
611
  * Generated bundle index. Do not edit.
588
612
  */
589
613
 
590
- export { AccountService, AdminService, AuthService, BETTER_AUTH_CONFIG_TOKEN, EmailOtpService, GenericOauthService, MagicLinkService, OneTapService, OrganizationService, PasskeyService, SessionService, TwoFactorService, canActivate, hasRole, provideBetterAuth, redirectLoggedInTo, redirectUnauthorizedTo };
614
+ export { AccountService, AdminService, AuthService, BETTER_AUTH_CONFIG_TOKEN, EmailOtpService, GenericOauthService, MagicLinkService, OneTapService, OrganizationService, PasskeyService, SessionService, TwoFactorService, UsernameService, canActivate, hasRole, provideBetterAuth, redirectLoggedInTo, redirectUnauthorizedTo };
591
615
  //# sourceMappingURL=ngx-better-auth.mjs.map