ngx-better-auth 0.1.0
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 +105 -0
- package/fesm2022/ngx-better-auth.mjs +199 -0
- package/fesm2022/ngx-better-auth.mjs.map +1 -0
- package/index.d.ts +99 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# ngx-better-auth
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
An **Angular 20+ integration for [Better Auth](https://github.com/better-auth/better-auth)**.
|
|
10
|
+
Provides reactive session handling with **signals**, clean **DI provider setup** with **observables**, and modern **guards**.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🚀 Compatibility
|
|
15
|
+
|
|
16
|
+
| ngx-better-auth | Angular | Better Auth |
|
|
17
|
+
|-----------------|---------|-------------|
|
|
18
|
+
| `^0.1.0` | `>=20` | `>=1.3.7` |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📦 Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install ngx-better-auth better-auth
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## ⚙️ Setup Provider
|
|
31
|
+
First, configure your Better Auth client in your application:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
// app.config.ts
|
|
35
|
+
import { ApplicationConfig } from '@angular/core'
|
|
36
|
+
import { provideBetterAuth } from 'ngx-better-auth'
|
|
37
|
+
|
|
38
|
+
export const appConfig: ApplicationConfig = {
|
|
39
|
+
providers: [
|
|
40
|
+
provideBetterAuth({
|
|
41
|
+
baseURL: 'http://localhost:3000', // your API endpoint
|
|
42
|
+
})
|
|
43
|
+
]
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 🧩 Different services
|
|
48
|
+
|
|
49
|
+
You can inject different services depending on your needs:
|
|
50
|
+
|
|
51
|
+
### Global services:
|
|
52
|
+
- `SessionService`
|
|
53
|
+
|
|
54
|
+
### Plugin services:
|
|
55
|
+
- `AdminService`
|
|
56
|
+
- `OrganizationService`
|
|
57
|
+
|
|
58
|
+
## 🔄 Real-time Session
|
|
59
|
+
|
|
60
|
+
### AuthService keeps the session in sync automatically
|
|
61
|
+
- `session` → a signal with the current session or null
|
|
62
|
+
- `isLoggedIn` → a computed boolean
|
|
63
|
+
|
|
64
|
+
### Demonstration of usage in a component
|
|
65
|
+
```ts
|
|
66
|
+
import { AuthService } from "ngx-better-auth"
|
|
67
|
+
import { inject } from "@angular/core"
|
|
68
|
+
|
|
69
|
+
private readonly auth = inject(AuthService)
|
|
70
|
+
if (this.auth.isLoggedIn()) {
|
|
71
|
+
console.log('Current user:', this.auth.session()?.user)
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 🛡️ Guards
|
|
76
|
+
This library ships with guards to quickly set up route protection.
|
|
77
|
+
|
|
78
|
+
### Helpers
|
|
79
|
+
- `redirectUnauthorizedTo(['/login'])` → redirect if not logged in
|
|
80
|
+
- `redirectLoggedInTo(['/'])` → redirect if already logged in
|
|
81
|
+
- `hasRole(['admin'], ['/unauthorized'])` → restrict access by role and redirect if not authorized
|
|
82
|
+
|
|
83
|
+
### Usage in routes
|
|
84
|
+
```ts
|
|
85
|
+
import { Routes } from '@angular/router'
|
|
86
|
+
import { canActivate, redirectLoggedInTo, redirectUnauthorizedTo, hasRole } from 'ngx-better-auth/guards'
|
|
87
|
+
|
|
88
|
+
export const routes: Routes = [
|
|
89
|
+
{
|
|
90
|
+
path: '',
|
|
91
|
+
component: SomeComponent,
|
|
92
|
+
...canActivate(redirectUnauthorizedTo(['/login']))
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
path: 'admin',
|
|
96
|
+
component: AdminComponent,
|
|
97
|
+
...canActivate(hasRole(['admin'], ['/unauthorized']))
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
path: 'login',
|
|
101
|
+
component: LoginComponent,
|
|
102
|
+
...canActivate(redirectLoggedInTo(['/']))
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
```
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, signal, computed, Injectable, InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { createAuthClient } from 'better-auth/client';
|
|
4
|
+
import { defer } from 'rxjs';
|
|
5
|
+
import { Router } from '@angular/router';
|
|
6
|
+
|
|
7
|
+
class AuthService {
|
|
8
|
+
config = inject(BETTER_AUTH_CONFIG_TOKEN);
|
|
9
|
+
authClient = createAuthClient({
|
|
10
|
+
...this.config,
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Current authenticated session
|
|
14
|
+
*/
|
|
15
|
+
session = signal(null, ...(ngDevMode ? [{ debugName: "session" }] : []));
|
|
16
|
+
/**
|
|
17
|
+
* Whether there is an active session
|
|
18
|
+
*/
|
|
19
|
+
isLoggedIn = computed(() => !!this.session()?.session, ...(ngDevMode ? [{ debugName: "isLoggedIn" }] : []));
|
|
20
|
+
constructor() {
|
|
21
|
+
this.session$();
|
|
22
|
+
}
|
|
23
|
+
session$() {
|
|
24
|
+
this.authClient.useSession.subscribe((session) => {
|
|
25
|
+
if (session.isPending) {
|
|
26
|
+
this.session.set(null);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (session.error) {
|
|
30
|
+
const error = session.error;
|
|
31
|
+
if (error.status !== 401) {
|
|
32
|
+
console.error('Error fetching session:', error);
|
|
33
|
+
}
|
|
34
|
+
this.session.set(null);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.session.set(session.data);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
41
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
42
|
+
}
|
|
43
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AuthService, decorators: [{
|
|
44
|
+
type: Injectable,
|
|
45
|
+
args: [{
|
|
46
|
+
providedIn: 'root',
|
|
47
|
+
}]
|
|
48
|
+
}], ctorParameters: () => [] });
|
|
49
|
+
|
|
50
|
+
const BETTER_AUTH_CONFIG_TOKEN = new InjectionToken('BETTER_AUTH_CONFIG');
|
|
51
|
+
const DEFAULT_CONFIG = {};
|
|
52
|
+
function provideBetterAuth(options) {
|
|
53
|
+
const config = { ...DEFAULT_CONFIG, ...options };
|
|
54
|
+
// if baseURL is not a url, it might be because of a proxy in development
|
|
55
|
+
if (!config.baseURL?.startsWith('http')) {
|
|
56
|
+
config.baseURL = window.location.origin + config.baseURL;
|
|
57
|
+
}
|
|
58
|
+
return makeEnvironmentProviders([{ provide: BETTER_AUTH_CONFIG_TOKEN, useValue: config }, AuthService]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function validateAdminPlugin(client, property) {
|
|
62
|
+
if (!client) {
|
|
63
|
+
throw new Error('AuthClient is not initialized.');
|
|
64
|
+
}
|
|
65
|
+
if (!client[property]) {
|
|
66
|
+
throw new Error(`Property '${property}' is not available on authClient. Please ensure the plugin providing this property is included in the plugins array.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class AdminService {
|
|
71
|
+
authService = inject(AuthService);
|
|
72
|
+
admin;
|
|
73
|
+
constructor() {
|
|
74
|
+
const client = this.authService.authClient;
|
|
75
|
+
validateAdminPlugin(client, 'admin');
|
|
76
|
+
this.admin = client.admin;
|
|
77
|
+
}
|
|
78
|
+
setRole(data) {
|
|
79
|
+
return defer(() => this.admin.setRole(data));
|
|
80
|
+
}
|
|
81
|
+
setUserPassword(data) {
|
|
82
|
+
return defer(() => this.admin.setUserPassword(data));
|
|
83
|
+
}
|
|
84
|
+
banUser(data) {
|
|
85
|
+
return defer(() => this.admin.banUser(data));
|
|
86
|
+
}
|
|
87
|
+
unbanUser(data) {
|
|
88
|
+
return defer(() => this.admin.unbanUser(data));
|
|
89
|
+
}
|
|
90
|
+
listUserSessions(data) {
|
|
91
|
+
return defer(() => this.admin.listUserSessions(data));
|
|
92
|
+
}
|
|
93
|
+
revokeUserSession(data) {
|
|
94
|
+
return defer(() => this.admin.revokeUserSession(data));
|
|
95
|
+
}
|
|
96
|
+
revokeUserSessions(data) {
|
|
97
|
+
return defer(() => this.admin.revokeUserSessions(data));
|
|
98
|
+
}
|
|
99
|
+
impersonateUser(data) {
|
|
100
|
+
return defer(() => this.admin.impersonateUser(data));
|
|
101
|
+
}
|
|
102
|
+
stopImpersonating() {
|
|
103
|
+
return defer(() => this.admin.stopImpersonating());
|
|
104
|
+
}
|
|
105
|
+
removeUser(data) {
|
|
106
|
+
return defer(() => this.admin.removeUser(data));
|
|
107
|
+
}
|
|
108
|
+
hasPermission(data) {
|
|
109
|
+
return defer(() => this.admin.hasPermission(data));
|
|
110
|
+
}
|
|
111
|
+
checkRolePermission(data) {
|
|
112
|
+
return this.admin.checkRolePermission(data);
|
|
113
|
+
}
|
|
114
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
115
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AdminService, providedIn: 'root' });
|
|
116
|
+
}
|
|
117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: AdminService, decorators: [{
|
|
118
|
+
type: Injectable,
|
|
119
|
+
args: [{ providedIn: 'root' }]
|
|
120
|
+
}], ctorParameters: () => [] });
|
|
121
|
+
|
|
122
|
+
class OrganizationService {
|
|
123
|
+
authService = inject(AuthService);
|
|
124
|
+
organization;
|
|
125
|
+
constructor() {
|
|
126
|
+
const client = this.authService.authClient;
|
|
127
|
+
validateAdminPlugin(client, 'organization');
|
|
128
|
+
this.organization = client.organization;
|
|
129
|
+
}
|
|
130
|
+
createOrganization(data) {
|
|
131
|
+
return defer(() => this.organization.create(data));
|
|
132
|
+
}
|
|
133
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OrganizationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
134
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OrganizationService, providedIn: 'root' });
|
|
135
|
+
}
|
|
136
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OrganizationService, decorators: [{
|
|
137
|
+
type: Injectable,
|
|
138
|
+
args: [{ providedIn: 'root' }]
|
|
139
|
+
}], ctorParameters: () => [] });
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Redirects unauthorized users to the specified commands (route).
|
|
143
|
+
*/
|
|
144
|
+
function redirectUnauthorizedTo(commands = ['/login']) {
|
|
145
|
+
return () => {
|
|
146
|
+
const auth = inject(AuthService);
|
|
147
|
+
const router = inject(Router);
|
|
148
|
+
return auth.isLoggedIn() ? true : router.createUrlTree(commands);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Redirects logged-in users to the specified commands (route).
|
|
153
|
+
*/
|
|
154
|
+
function redirectLoggedInTo(commands = ['/']) {
|
|
155
|
+
return () => {
|
|
156
|
+
const auth = inject(AuthService);
|
|
157
|
+
const router = inject(Router);
|
|
158
|
+
return auth.isLoggedIn() ? router.createUrlTree(commands) : true;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Allows access only to users with at least one of the specified roles.
|
|
163
|
+
* Redirects unauthorized users to the specified commands (route).
|
|
164
|
+
*/
|
|
165
|
+
function hasRole(requiredRoles, redirectTo = ['/unauthorized']) {
|
|
166
|
+
return () => {
|
|
167
|
+
const auth = inject(AuthService);
|
|
168
|
+
const router = inject(Router);
|
|
169
|
+
const session = auth.session();
|
|
170
|
+
if (!session || !session.user) {
|
|
171
|
+
return router.createUrlTree(redirectTo);
|
|
172
|
+
}
|
|
173
|
+
const role = session?.user?.role;
|
|
174
|
+
if (Array.isArray(role)) {
|
|
175
|
+
if (role.some((r) => requiredRoles.includes(r))) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (typeof role === 'string') {
|
|
180
|
+
if (requiredRoles.includes(role)) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return router.createUrlTree(redirectTo);
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function canActivate(pipe) {
|
|
189
|
+
return {
|
|
190
|
+
canActivate: [() => pipe()],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Generated bundle index. Do not edit.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
export { AdminService, BETTER_AUTH_CONFIG_TOKEN, OrganizationService, canActivate, hasRole, provideBetterAuth, redirectLoggedInTo, redirectUnauthorizedTo };
|
|
199
|
+
//# sourceMappingURL=ngx-better-auth.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-better-auth.mjs","sources":["../../../src/lib/services/auth.service.ts","../../../src/lib/providers.ts","../../../src/lib/utils/validate-plugin.ts","../../../src/lib/services/admin.service.ts","../../../src/lib/services/organization.service.ts","../../../src/lib/guards/auth-guard.utils.ts","../../../src/lib/guards/auth-guard.factory.ts","../../../src/ngx-better-auth.ts"],"sourcesContent":["import { computed, inject, Injectable, signal } from '@angular/core'\nimport { BETTER_AUTH_CONFIG_TOKEN } from '../providers'\nimport { BetterFetchError, createAuthClient } from 'better-auth/client'\nimport { AuthSession } from '../models'\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly config = inject(BETTER_AUTH_CONFIG_TOKEN)\n\n readonly authClient = createAuthClient({\n ...this.config,\n })\n\n /**\n * Current authenticated session\n */\n readonly session = signal<AuthSession | null>(null)\n\n /**\n * Whether there is an active session\n */\n readonly isLoggedIn = computed(() => !!this.session()?.session)\n\n constructor() {\n this.session$()\n }\n\n private session$() {\n this.authClient.useSession.subscribe((session) => {\n if (session.isPending) {\n this.session.set(null)\n return\n }\n if (session.error) {\n const error: BetterFetchError = session.error\n if (error.status !== 401) {\n console.error('Error fetching session:', error)\n }\n this.session.set(null)\n return\n }\n this.session.set(session.data)\n })\n }\n}\n","import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core'\nimport { type BetterAuthOptions } from 'better-auth'\nimport { AuthService } from './services/auth.service'\n\nexport const BETTER_AUTH_CONFIG_TOKEN = new InjectionToken<BetterAuthOptions>('BETTER_AUTH_CONFIG')\n\nconst DEFAULT_CONFIG: Partial<BetterAuthOptions> = {}\n\nexport function provideBetterAuth(options: BetterAuthOptions): EnvironmentProviders {\n const config: BetterAuthOptions = { ...DEFAULT_CONFIG, ...options }\n\n // if baseURL is not a url, it might be because of a proxy in development\n if (!config.baseURL?.startsWith('http')) {\n config.baseURL = window.location.origin + config.baseURL\n }\n\n return makeEnvironmentProviders([{ provide: BETTER_AUTH_CONFIG_TOKEN, useValue: config }, AuthService])\n}\n","export function validateAdminPlugin(client: any, property: string) {\n if (!client) {\n throw new Error('AuthClient is not initialized.')\n }\n\n if (!client[property]) {\n throw new Error(\n `Property '${property}' is not available on authClient. Please ensure the plugin providing this property is included in the plugins array.`,\n )\n }\n}\n","import { inject, Injectable } from '@angular/core'\nimport { defer } from 'rxjs'\nimport { AuthService } from './auth.service'\nimport { validateAdminPlugin } from '../utils/validate-plugin'\n\n@Injectable({ providedIn: 'root' })\nexport class AdminService {\n private readonly authService = inject(AuthService)\n\n admin: any\n\n constructor() {\n const client = this.authService.authClient as { admin?: any }\n validateAdminPlugin(client, 'admin')\n this.admin = client.admin\n }\n\n setRole(data: { userId: string; role: any }) {\n return defer(() => this.admin.setRole(data))\n }\n\n setUserPassword(data: { userId: string; newPassword: string }) {\n return defer(() => this.admin.setUserPassword(data))\n }\n\n banUser(data: { userId: string; banReason?: string; banExpiresIn?: number }) {\n return defer(() => this.admin.banUser(data))\n }\n\n unbanUser(data: { userId: string }) {\n return defer(() => this.admin.unbanUser(data))\n }\n\n listUserSessions(data: { userId: string }) {\n return defer(() => this.admin.listUserSessions(data))\n }\n\n revokeUserSession(data: { sessionToken: string }) {\n return defer(() => this.admin.revokeUserSession(data))\n }\n\n revokeUserSessions(data: { userId: string }) {\n return defer(() => this.admin.revokeUserSessions(data))\n }\n\n impersonateUser(data: { userId: string }) {\n return defer(() => this.admin.impersonateUser(data))\n }\n\n stopImpersonating() {\n return defer(() => this.admin.stopImpersonating())\n }\n\n removeUser(data: { userId: string }) {\n return defer(() => this.admin.removeUser(data))\n }\n\n hasPermission(data: { userId?: string; permission?: any; permissions?: any }) {\n return defer(() => this.admin.hasPermission(data))\n }\n\n checkRolePermission(data: { role: any; permission: any }) {\n return this.admin.checkRolePermission(data)\n }\n}\n","import { inject, Injectable } from '@angular/core'\nimport { defer } from 'rxjs'\nimport { AuthService } from './auth.service'\nimport { validateAdminPlugin } from '../utils/validate-plugin'\n\n@Injectable({ providedIn: 'root' })\nexport class OrganizationService {\n private readonly authService = inject(AuthService)\n\n organization: any\n\n constructor() {\n const client = this.authService.authClient as { organization?: any }\n validateAdminPlugin(client, 'organization')\n this.organization = client.organization\n }\n\n createOrganization(data: { name: string; slug: string }) {\n return defer(() => this.organization.create(data))\n }\n}\n","import { inject } from '@angular/core'\nimport { Router, UrlTree } from '@angular/router'\nimport { AuthService } from '../services/auth.service'\n\n/**\n * Redirects unauthorized users to the specified commands (route).\n */\nexport function redirectUnauthorizedTo(commands: string[] = ['/login']): () => UrlTree | boolean {\n return () => {\n const auth = inject(AuthService)\n const router = inject(Router)\n return auth.isLoggedIn() ? true : router.createUrlTree(commands)\n }\n}\n\n/**\n * Redirects logged-in users to the specified commands (route).\n */\nexport function redirectLoggedInTo(commands: string[] = ['/']): () => UrlTree | boolean {\n return () => {\n const auth = inject(AuthService)\n const router = inject(Router)\n return auth.isLoggedIn() ? router.createUrlTree(commands) : true\n }\n}\n\n/**\n * Allows access only to users with at least one of the specified roles.\n * Redirects unauthorized users to the specified commands (route).\n */\nexport function hasRole(requiredRoles: string[], redirectTo: string[] = ['/unauthorized']): () => UrlTree | boolean {\n return () => {\n const auth = inject(AuthService)\n const router = inject(Router)\n\n const session = auth.session()\n if (!session || !session.user) {\n return router.createUrlTree(redirectTo)\n }\n\n const role = session?.user?.role\n if (Array.isArray(role)) {\n if (role.some((r) => requiredRoles.includes(r))) {\n return true\n }\n } else if (typeof role === 'string') {\n if (requiredRoles.includes(role)) {\n return true\n }\n }\n\n return router.createUrlTree(redirectTo)\n }\n}\n","import { CanActivateFn } from '@angular/router'\n\nexport function canActivate(pipe: () => boolean | import('@angular/router').UrlTree): { canActivate: [CanActivateFn] } {\n return {\n canActivate: [() => pipe()],\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, EnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { BetterAuthOptions } from 'better-auth';
|
|
4
|
+
import * as rxjs from 'rxjs';
|
|
5
|
+
import { Session, User } from 'better-auth/types';
|
|
6
|
+
import * as _angular_router from '@angular/router';
|
|
7
|
+
import { UrlTree, CanActivateFn } from '@angular/router';
|
|
8
|
+
|
|
9
|
+
declare const BETTER_AUTH_CONFIG_TOKEN: InjectionToken<BetterAuthOptions>;
|
|
10
|
+
declare function provideBetterAuth(options: BetterAuthOptions): EnvironmentProviders;
|
|
11
|
+
|
|
12
|
+
declare class AdminService {
|
|
13
|
+
private readonly authService;
|
|
14
|
+
admin: any;
|
|
15
|
+
constructor();
|
|
16
|
+
setRole(data: {
|
|
17
|
+
userId: string;
|
|
18
|
+
role: any;
|
|
19
|
+
}): rxjs.Observable<unknown>;
|
|
20
|
+
setUserPassword(data: {
|
|
21
|
+
userId: string;
|
|
22
|
+
newPassword: string;
|
|
23
|
+
}): rxjs.Observable<unknown>;
|
|
24
|
+
banUser(data: {
|
|
25
|
+
userId: string;
|
|
26
|
+
banReason?: string;
|
|
27
|
+
banExpiresIn?: number;
|
|
28
|
+
}): rxjs.Observable<unknown>;
|
|
29
|
+
unbanUser(data: {
|
|
30
|
+
userId: string;
|
|
31
|
+
}): rxjs.Observable<unknown>;
|
|
32
|
+
listUserSessions(data: {
|
|
33
|
+
userId: string;
|
|
34
|
+
}): rxjs.Observable<unknown>;
|
|
35
|
+
revokeUserSession(data: {
|
|
36
|
+
sessionToken: string;
|
|
37
|
+
}): rxjs.Observable<unknown>;
|
|
38
|
+
revokeUserSessions(data: {
|
|
39
|
+
userId: string;
|
|
40
|
+
}): rxjs.Observable<unknown>;
|
|
41
|
+
impersonateUser(data: {
|
|
42
|
+
userId: string;
|
|
43
|
+
}): rxjs.Observable<unknown>;
|
|
44
|
+
stopImpersonating(): rxjs.Observable<unknown>;
|
|
45
|
+
removeUser(data: {
|
|
46
|
+
userId: string;
|
|
47
|
+
}): rxjs.Observable<unknown>;
|
|
48
|
+
hasPermission(data: {
|
|
49
|
+
userId?: string;
|
|
50
|
+
permission?: any;
|
|
51
|
+
permissions?: any;
|
|
52
|
+
}): rxjs.Observable<unknown>;
|
|
53
|
+
checkRolePermission(data: {
|
|
54
|
+
role: any;
|
|
55
|
+
permission: any;
|
|
56
|
+
}): any;
|
|
57
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AdminService, never>;
|
|
58
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AdminService>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare class OrganizationService {
|
|
62
|
+
private readonly authService;
|
|
63
|
+
organization: any;
|
|
64
|
+
constructor();
|
|
65
|
+
createOrganization(data: {
|
|
66
|
+
name: string;
|
|
67
|
+
slug: string;
|
|
68
|
+
}): rxjs.Observable<unknown>;
|
|
69
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OrganizationService, never>;
|
|
70
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<OrganizationService>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface AuthSession {
|
|
74
|
+
session: Session;
|
|
75
|
+
user: User & {
|
|
76
|
+
role?: string[] | string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Redirects unauthorized users to the specified commands (route).
|
|
82
|
+
*/
|
|
83
|
+
declare function redirectUnauthorizedTo(commands?: string[]): () => UrlTree | boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Redirects logged-in users to the specified commands (route).
|
|
86
|
+
*/
|
|
87
|
+
declare function redirectLoggedInTo(commands?: string[]): () => UrlTree | boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Allows access only to users with at least one of the specified roles.
|
|
90
|
+
* Redirects unauthorized users to the specified commands (route).
|
|
91
|
+
*/
|
|
92
|
+
declare function hasRole(requiredRoles: string[], redirectTo?: string[]): () => UrlTree | boolean;
|
|
93
|
+
|
|
94
|
+
declare function canActivate(pipe: () => boolean | _angular_router.UrlTree): {
|
|
95
|
+
canActivate: [CanActivateFn];
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export { AdminService, BETTER_AUTH_CONFIG_TOKEN, OrganizationService, canActivate, hasRole, provideBetterAuth, redirectLoggedInTo, redirectUnauthorizedTo };
|
|
99
|
+
export type { AuthSession };
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ngx-better-auth",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/core": ">=20.0.0",
|
|
6
|
+
"@angular/common": ">=20.0.0",
|
|
7
|
+
"@angular/router": ">=20.0.0",
|
|
8
|
+
"better-auth": ">=1.3.7",
|
|
9
|
+
"rxjs": ">=7.8.0"
|
|
10
|
+
},
|
|
11
|
+
"module": "fesm2022/ngx-better-auth.mjs",
|
|
12
|
+
"typings": "index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
"./package.json": {
|
|
15
|
+
"default": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./index.d.ts",
|
|
19
|
+
"default": "./fesm2022/ngx-better-auth.mjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"tslib": ">=2.3.0"
|
|
25
|
+
}
|
|
26
|
+
}
|