@anarchitects/auth-angular 0.0.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.
@@ -0,0 +1,175 @@
1
+ import { AuthApi } from '@anarchitects/auth-angular/data-access';
2
+ import { createAppAbility } from '@anarchitects/auth-angular/util';
3
+ import { inject, computed } from '@angular/core';
4
+ import { tapResponse } from '@ngrx/operators';
5
+ import { signalStore, withState, withProps, withComputed, withMethods, patchState } from '@ngrx/signals';
6
+ import { withEntities, setAllEntities, removeAllEntities } from '@ngrx/signals/entities';
7
+ import { rxMethod } from '@ngrx/signals/rxjs-interop';
8
+ import { jwtDecode } from 'jwt-decode';
9
+ import { pipe, tap, switchMap, EMPTY } from 'rxjs';
10
+
11
+ const initialState = {
12
+ loading: false,
13
+ error: null,
14
+ success: false,
15
+ ability: undefined,
16
+ };
17
+ const AuthStore = signalStore({ providedIn: 'root' }, withState(initialState), withEntities(), withProps(() => ({
18
+ _authApi: inject(AuthApi),
19
+ })), withComputed((store) => ({
20
+ isLoggedIn: computed(() => !!store.entities().length),
21
+ loggedInUser: computed(() => store.entities()[0]),
22
+ })), withMethods((store) => ({
23
+ registerUser: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.registerUser(dto).pipe(tapResponse({
24
+ next: ({ success }) => {
25
+ patchState(store, { success });
26
+ },
27
+ error: (error) => {
28
+ patchState(store, { error });
29
+ },
30
+ finalize: () => {
31
+ patchState(store, { loading: false });
32
+ },
33
+ }))))),
34
+ activateUser: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.activateUser(dto).pipe(tapResponse({
35
+ next: ({ success }) => {
36
+ patchState(store, { success });
37
+ },
38
+ error: (error) => {
39
+ patchState(store, { error });
40
+ },
41
+ finalize: () => {
42
+ patchState(store, { loading: false });
43
+ },
44
+ }))))),
45
+ login: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.login(dto).pipe(switchMap(({ accessToken, refreshToken }) => {
46
+ localStorage.setItem('accessToken', accessToken);
47
+ localStorage.setItem('refreshToken', refreshToken);
48
+ const decoded = jwtDecode(accessToken);
49
+ if (!decoded.sub) {
50
+ patchState(store, { error: 'Invalid access token payload.' });
51
+ return EMPTY;
52
+ }
53
+ return store._authApi.getLoggedInUserInfo();
54
+ }), tapResponse({
55
+ next: ({ user, rbac }) => {
56
+ const authUser = {
57
+ id: user.id,
58
+ email: user.email,
59
+ };
60
+ patchState(store, setAllEntities([authUser]), {
61
+ ability: createAppAbility(rbac),
62
+ success: true,
63
+ });
64
+ },
65
+ error: (error) => {
66
+ patchState(store, { error });
67
+ },
68
+ finalize: () => {
69
+ patchState(store, { loading: false });
70
+ },
71
+ }))))),
72
+ logout: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.logout(dto).pipe(tapResponse({
73
+ next: ({ success }) => {
74
+ patchState(store, { success });
75
+ localStorage.removeItem('accessToken');
76
+ localStorage.removeItem('refreshToken');
77
+ patchState(store, removeAllEntities());
78
+ },
79
+ error: (error) => {
80
+ patchState(store, { error });
81
+ },
82
+ finalize: () => {
83
+ patchState(store, { loading: false });
84
+ },
85
+ }))))),
86
+ changePassword: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap(({ userId, dto }) => store._authApi.changePassword(userId, dto).pipe(tapResponse({
87
+ next: ({ success }) => {
88
+ patchState(store, { success });
89
+ },
90
+ error: (error) => {
91
+ patchState(store, { error });
92
+ },
93
+ finalize: () => {
94
+ patchState(store, { loading: false });
95
+ },
96
+ }))))),
97
+ forgotPassword: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.forgotPassword(dto).pipe(tapResponse({
98
+ next: ({ success }) => {
99
+ patchState(store, { success });
100
+ },
101
+ error: (error) => {
102
+ patchState(store, { error });
103
+ },
104
+ finalize: () => {
105
+ patchState(store, { loading: false });
106
+ },
107
+ }))))),
108
+ resetPassword: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap(({ dto }) => store._authApi.resetPassword(dto).pipe(tapResponse({
109
+ next: ({ success }) => {
110
+ patchState(store, { success });
111
+ },
112
+ error: (error) => {
113
+ patchState(store, { error });
114
+ },
115
+ finalize: () => {
116
+ patchState(store, { loading: false });
117
+ },
118
+ }))))),
119
+ verifyEmail: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap((dto) => store._authApi.verifyEmail(dto).pipe(tapResponse({
120
+ next: ({ success }) => {
121
+ patchState(store, { success });
122
+ },
123
+ error: (error) => {
124
+ patchState(store, { error });
125
+ },
126
+ finalize: () => {
127
+ patchState(store, { loading: false });
128
+ },
129
+ }))))),
130
+ updateEmail: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap(({ userId, dto }) => store._authApi.updateEmail(userId, dto).pipe(tapResponse({
131
+ next: ({ success }) => {
132
+ patchState(store, { success });
133
+ },
134
+ error: (error) => {
135
+ patchState(store, { error });
136
+ },
137
+ finalize: () => {
138
+ patchState(store, { loading: false });
139
+ },
140
+ }))))),
141
+ refreshTokens: rxMethod(pipe(tap(() => patchState(store, { loading: true, error: null })), switchMap(({ userId, dto }) => store._authApi.refreshTokens(userId, dto).pipe(switchMap(({ accessToken, refreshToken }) => {
142
+ localStorage.setItem('accessToken', accessToken);
143
+ localStorage.setItem('refreshToken', refreshToken);
144
+ const decoded = jwtDecode(accessToken);
145
+ if (!decoded.sub) {
146
+ patchState(store, { error: 'Invalid access token payload.' });
147
+ return EMPTY;
148
+ }
149
+ return store._authApi.getLoggedInUserInfo();
150
+ }), tapResponse({
151
+ next: ({ user, rbac }) => {
152
+ const authUser = {
153
+ id: user.id,
154
+ email: user.email,
155
+ };
156
+ patchState(store, setAllEntities([authUser]), {
157
+ ability: createAppAbility(rbac),
158
+ success: true,
159
+ });
160
+ },
161
+ error: (error) => {
162
+ patchState(store, { error });
163
+ },
164
+ finalize: () => {
165
+ patchState(store, { loading: false });
166
+ },
167
+ }))))),
168
+ })));
169
+
170
+ /**
171
+ * Generated bundle index. Do not edit.
172
+ */
173
+
174
+ export { AuthStore };
175
+ //# sourceMappingURL=anarchitects-auth-angular-state.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anarchitects-auth-angular-state.mjs","sources":["../../../../../libs/auth/angular/state/src/auth.store.ts","../../../../../libs/auth/angular/state/src/anarchitects-auth-angular-state.ts"],"sourcesContent":["import { AuthApi } from '@anarchitects/auth-angular/data-access';\nimport { createAppAbility } from '@anarchitects/auth-angular/util';\nimport {\n ActivateUserRequestDTO,\n ChangePasswordRequestDTO,\n ForgotPasswordRequestDTO,\n LoginRequestDTO,\n LogoutRequestDTO,\n RefreshTokenRequestDTO,\n RegisterRequestDTO,\n ResetPasswordRequestDTO,\n UpdateEmailRequestDTO,\n VerifyEmailRequestDTO,\n} from '@anarchitects/auth-ts/dtos';\nimport { User } from '@anarchitects/auth-ts/models';\nimport { computed, inject } from '@angular/core';\nimport { PureAbility } from '@casl/ability';\nimport { tapResponse } from '@ngrx/operators';\nimport {\n patchState,\n signalStore,\n withComputed,\n withMethods,\n withProps,\n withState,\n} from '@ngrx/signals';\nimport {\n removeAllEntities,\n setAllEntities,\n withEntities,\n} from '@ngrx/signals/entities';\nimport { rxMethod } from '@ngrx/signals/rxjs-interop';\nimport { jwtDecode } from 'jwt-decode';\nimport { EMPTY, pipe, switchMap, tap } from 'rxjs';\n\ntype AuthState = {\n loading: boolean;\n error: string | null;\n success: boolean;\n ability?: PureAbility;\n};\n\ntype AuthUser = Pick<User, 'id' | 'email'>;\n\nconst initialState: AuthState = {\n loading: false,\n error: null,\n success: false,\n ability: undefined,\n};\n\nexport const AuthStore = signalStore(\n { providedIn: 'root' },\n withState(initialState),\n withEntities<AuthUser>(),\n withProps(() => ({\n _authApi: inject(AuthApi),\n })),\n withComputed((store) => ({\n isLoggedIn: computed(() => !!store.entities().length),\n loggedInUser: computed(() => store.entities()[0]),\n })),\n withMethods((store) => ({\n registerUser: rxMethod<RegisterRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.registerUser(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n activateUser: rxMethod<ActivateUserRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.activateUser(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n login: rxMethod<LoginRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.login(dto).pipe(\n switchMap(({ accessToken, refreshToken }) => {\n localStorage.setItem('accessToken', accessToken);\n localStorage.setItem('refreshToken', refreshToken);\n const decoded = jwtDecode<{ sub?: string }>(accessToken);\n if (!decoded.sub) {\n patchState(store, { error: 'Invalid access token payload.' });\n return EMPTY;\n }\n return store._authApi.getLoggedInUserInfo();\n }),\n tapResponse({\n next: ({ user, rbac }) => {\n const authUser: AuthUser = {\n id: user.id,\n email: user.email,\n };\n patchState(store, setAllEntities([authUser]), {\n ability: createAppAbility(rbac),\n success: true,\n });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n logout: rxMethod<LogoutRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.logout(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n localStorage.removeItem('accessToken');\n localStorage.removeItem('refreshToken');\n patchState(store, removeAllEntities());\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n changePassword: rxMethod<{ userId: string; dto: ChangePasswordRequestDTO }>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap(({ userId, dto }) =>\n store._authApi.changePassword(userId, dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n forgotPassword: rxMethod<ForgotPasswordRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.forgotPassword(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n resetPassword: rxMethod<{ dto: ResetPasswordRequestDTO }>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap(({ dto }) =>\n store._authApi.resetPassword(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n verifyEmail: rxMethod<VerifyEmailRequestDTO>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap((dto) =>\n store._authApi.verifyEmail(dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n updateEmail: rxMethod<{ userId: string; dto: UpdateEmailRequestDTO }>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap(({ userId, dto }) =>\n store._authApi.updateEmail(userId, dto).pipe(\n tapResponse({\n next: ({ success }) => {\n patchState(store, { success });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n refreshTokens: rxMethod<{ userId: string; dto: RefreshTokenRequestDTO }>(\n pipe(\n tap(() => patchState(store, { loading: true, error: null })),\n switchMap(({ userId, dto }) =>\n store._authApi.refreshTokens(userId, dto).pipe(\n switchMap(({ accessToken, refreshToken }) => {\n localStorage.setItem('accessToken', accessToken);\n localStorage.setItem('refreshToken', refreshToken);\n const decoded = jwtDecode<{ sub?: string }>(accessToken);\n if (!decoded.sub) {\n patchState(store, { error: 'Invalid access token payload.' });\n return EMPTY;\n }\n return store._authApi.getLoggedInUserInfo();\n }),\n tapResponse({\n next: ({ user, rbac }) => {\n const authUser: AuthUser = {\n id: user.id,\n email: user.email,\n };\n patchState(store, setAllEntities([authUser]), {\n ability: createAppAbility(rbac),\n success: true,\n });\n },\n error: (error: string) => {\n patchState(store, { error });\n },\n finalize: () => {\n patchState(store, { loading: false });\n },\n })\n )\n )\n )\n ),\n }))\n);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { createMongoAbility } from '@casl/ability';
2
+
3
+ const createAppAbility = (rules) => createMongoAbility(rules);
4
+
5
+ /**
6
+ * Generated bundle index. Do not edit.
7
+ */
8
+
9
+ export { createAppAbility };
10
+ //# sourceMappingURL=anarchitects-auth-angular-util.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anarchitects-auth-angular-util.mjs","sources":["../../../../../libs/auth/angular/util/src/ability.factory.ts","../../../../../libs/auth/angular/util/src/anarchitects-auth-angular-util.ts"],"sourcesContent":["import { Action, PolicyRule, Subject } from '@anarchitects/auth-ts/models';\nimport { createMongoAbility, MongoAbility } from '@casl/ability';\n\ntype AbilitySubject =\n | Subject\n | (Record<string, unknown> & { __caslSubjectType__?: Subject });\n\nexport type AppAbility = MongoAbility<\n [Action, AbilitySubject],\n { conditions: Record<string, unknown> }\n>;\n\nexport const createAppAbility = (rules: PolicyRule[]) =>\n createMongoAbility(rules);\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAYO,MAAM,gBAAgB,GAAG,CAAC,KAAmB,KAClD,kBAAkB,CAAC,KAAK;;ACb1B;;AAEG;;;;"}
@@ -0,0 +1,10 @@
1
+ export * from '@anarchitects/auth-angular/config';
2
+ export * from '@anarchitects/auth-angular/data-access';
3
+ export * from '@anarchitects/auth-angular/feature';
4
+ export * from '@anarchitects/auth-angular/state';
5
+ export * from '@anarchitects/auth-angular/util';
6
+
7
+ /**
8
+ * Generated bundle index. Do not edit.
9
+ */
10
+ //# sourceMappingURL=anarchitects-auth-angular.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anarchitects-auth-angular.mjs","sources":["../../../../../libs/auth/angular/src/anarchitects-auth-angular.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAAA;;AAEG"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@anarchitects/auth-angular",
3
+ "version": "0.0.1",
4
+ "peerDependencies": {
5
+ "@angular/common": "21.1.6",
6
+ "@angular/core": "21.1.6",
7
+ "@anarchitects/auth-ts": "0.0.1",
8
+ "@anarchitects/forms-angular": "0.0.6",
9
+ "@anarchitects/forms-ts": "0.0.5",
10
+ "@ngrx/signals": "^20.0.1",
11
+ "@ngrx/operators": "^20.0.1",
12
+ "rxjs": "~7.8.0",
13
+ "jwt-decode": "^4.0.0",
14
+ "@casl/ability": "^6.7.3",
15
+ "@angular/router": "21.1.6"
16
+ },
17
+ "sideEffects": false,
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "module": "fesm2022/anarchitects-auth-angular.mjs",
22
+ "typings": "types/anarchitects-auth-angular.d.ts",
23
+ "exports": {
24
+ "./package.json": {
25
+ "default": "./package.json"
26
+ },
27
+ ".": {
28
+ "types": "./types/anarchitects-auth-angular.d.ts",
29
+ "default": "./fesm2022/anarchitects-auth-angular.mjs"
30
+ },
31
+ "./config": {
32
+ "types": "./types/anarchitects-auth-angular-config.d.ts",
33
+ "default": "./fesm2022/anarchitects-auth-angular-config.mjs"
34
+ },
35
+ "./data-access": {
36
+ "types": "./types/anarchitects-auth-angular-data-access.d.ts",
37
+ "default": "./fesm2022/anarchitects-auth-angular-data-access.mjs"
38
+ },
39
+ "./feature": {
40
+ "types": "./types/anarchitects-auth-angular-feature.d.ts",
41
+ "default": "./fesm2022/anarchitects-auth-angular-feature.mjs"
42
+ },
43
+ "./state": {
44
+ "types": "./types/anarchitects-auth-angular-state.d.ts",
45
+ "default": "./fesm2022/anarchitects-auth-angular-state.mjs"
46
+ },
47
+ "./util": {
48
+ "types": "./types/anarchitects-auth-angular-util.d.ts",
49
+ "default": "./fesm2022/anarchitects-auth-angular-util.mjs"
50
+ }
51
+ },
52
+ "dependencies": {
53
+ "tslib": "^2.3.0"
54
+ }
55
+ }
@@ -0,0 +1,34 @@
1
+ # @anarchitects/auth-angular/state
2
+
3
+ Signal-based state management for the auth domain. Import from `@anarchitects/auth-angular/state` to orchestrate login, logout, password resets, token refresh, and related workflows without wiring up NgRx reducers manually.
4
+
5
+ ## Exports
6
+
7
+ - `AuthStore`: an Angular `signalStore` that exposes:
8
+ - computed selectors (`isLoggedIn`, `loggedInUser`)
9
+ - async methods for each auth use case (`login`, `logout`, `registerUser`, etc.)
10
+ - The store depends on `AuthApi` from the data-access layer and respects the configuration providers.
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import { Component, inject } from '@angular/core';
16
+ import { AuthStore } from '@anarchitects/auth-angular/state';
17
+
18
+ @Component({
19
+ selector: 'auth-login-button',
20
+ template: `
21
+ <button (click)="onLogin()" [disabled]="store.loading()">Sign in</button>
22
+ <p *ngIf="store.error()">{{ store.error() }}</p>
23
+ `,
24
+ })
25
+ export class AuthLoginButtonComponent {
26
+ readonly store = inject(AuthStore);
27
+
28
+ onLogin() {
29
+ this.store.login({ credential: 'user@example.com', password: 'secret' });
30
+ }
31
+ }
32
+ ```
33
+
34
+ Compose the store inside smart/feature components or facades; keep UI components dumb by binding to the store's signals.
@@ -0,0 +1,18 @@
1
+ import { InjectionToken, Provider } from '@angular/core';
2
+
3
+ type AuthConfig = {
4
+ apiResourcePath: string;
5
+ };
6
+ declare const AUTH_CONFIG: InjectionToken<AuthConfig>;
7
+ declare const API_RESOURCE_PATH: InjectionToken<string>;
8
+ /** Library-level sensible defaults */
9
+ declare const AUTH_DEFAULTS: AuthConfig;
10
+ /** Safe injectors that fall back to defaults if no providers are registered */
11
+ declare function injectAuthConfig(): AuthConfig;
12
+ declare function injectApiResourcePath(): string;
13
+
14
+ declare function provideAuthConfig(cfg: Partial<AuthConfig>): Provider[];
15
+ declare function provideAuthDefaults(): Provider[];
16
+
17
+ export { API_RESOURCE_PATH, AUTH_CONFIG, AUTH_DEFAULTS, injectApiResourcePath, injectAuthConfig, provideAuthConfig, provideAuthDefaults };
18
+ export type { AuthConfig };
@@ -0,0 +1,58 @@
1
+ import * as rxjs from 'rxjs';
2
+ import { RegisterRequestDTO, ActivateUserRequestDTO, LoginRequestDTO, LogoutRequestDTO, ChangePasswordRequestDTO, ForgotPasswordRequestDTO, ResetPasswordRequestDTO, VerifyEmailRequestDTO, UpdateEmailRequestDTO, RefreshTokenRequestDTO } from '@anarchitects/auth-ts/dtos';
3
+ import { User, PolicyRule } from '@anarchitects/auth-ts/models';
4
+ import * as i0 from '@angular/core';
5
+ import * as _angular_common_http from '@angular/common/http';
6
+ import { HttpInterceptorFn } from '@angular/common/http';
7
+
8
+ declare class AuthApi {
9
+ private readonly http;
10
+ private readonly resourceUrl;
11
+ registerUser(dto: RegisterRequestDTO): rxjs.Observable<{
12
+ success: boolean;
13
+ }>;
14
+ activateUser(dto: ActivateUserRequestDTO): rxjs.Observable<{
15
+ success: boolean;
16
+ }>;
17
+ login(dto: LoginRequestDTO): rxjs.Observable<{
18
+ accessToken: string;
19
+ refreshToken: string;
20
+ }>;
21
+ logout(dto: LogoutRequestDTO): rxjs.Observable<{
22
+ success: boolean;
23
+ }>;
24
+ changePassword(userId: string, dto: ChangePasswordRequestDTO): rxjs.Observable<{
25
+ success: boolean;
26
+ }>;
27
+ forgotPassword(dto: ForgotPasswordRequestDTO): rxjs.Observable<{
28
+ success: boolean;
29
+ }>;
30
+ resetPassword(dto: ResetPasswordRequestDTO): rxjs.Observable<{
31
+ success: boolean;
32
+ }>;
33
+ verifyEmail(dto: VerifyEmailRequestDTO): rxjs.Observable<{
34
+ success: boolean;
35
+ }>;
36
+ updateEmail(userId: string, dto: UpdateEmailRequestDTO): rxjs.Observable<{
37
+ success: boolean;
38
+ }>;
39
+ refreshTokens(userId: string, dto: RefreshTokenRequestDTO): rxjs.Observable<{
40
+ accessToken: string;
41
+ refreshToken: string;
42
+ }>;
43
+ getLoggedInUserInfo(): rxjs.Observable<{
44
+ user: User;
45
+ rbac: PolicyRule[];
46
+ }>;
47
+ static ɵfac: i0.ɵɵFactoryDeclaration<AuthApi, never>;
48
+ static ɵprov: i0.ɵɵInjectableDeclaration<AuthApi>;
49
+ }
50
+
51
+ declare const authBearerTokenInterceptor: HttpInterceptorFn;
52
+
53
+ declare const authErrorInterceptor: HttpInterceptorFn;
54
+
55
+ declare const AUTH_HTTP_INTERCEPTORS: HttpInterceptorFn[];
56
+ declare function withAuthHttpInterceptors(): _angular_common_http.HttpFeature<_angular_common_http.HttpFeatureKind.Interceptors>;
57
+
58
+ export { AUTH_HTTP_INTERCEPTORS, AuthApi, authBearerTokenInterceptor, authErrorInterceptor, withAuthHttpInterceptors };
@@ -0,0 +1,97 @@
1
+ import * as i0 from '@angular/core';
2
+ import { SubmissionRequestDTO } from '@anarchitects/forms-ts/dtos';
3
+ import { FormConfig } from '@anarchitects/forms-ts/models';
4
+ import { CanMatchFn } from '@angular/router';
5
+
6
+ declare class AnarchitectsFeatureRegister {
7
+ private readonly authStore;
8
+ formConfig: i0.WritableSignal<FormConfig>;
9
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureRegister, never>;
11
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureRegister, "anarchitects-auth-feature-register", never, {}, {}, never, never, true, never>;
12
+ }
13
+
14
+ declare class AnarchitectsFeatureActivateUser {
15
+ private readonly authStore;
16
+ readonly token: i0.InputSignal<string | undefined>;
17
+ readonly formConfig: i0.Signal<FormConfig>;
18
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureActivateUser, never>;
20
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureActivateUser, "anarchitects-auth-feature-activate-user", never, { "token": { "alias": "token"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
21
+ }
22
+
23
+ declare class AnarchitectsFeatureForgotPassword {
24
+ private readonly authStore;
25
+ readonly formConfig: i0.WritableSignal<FormConfig>;
26
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
27
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureForgotPassword, never>;
28
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureForgotPassword, "anarchitects-auth-feature-forgot-password", never, {}, {}, never, never, true, never>;
29
+ }
30
+
31
+ declare class AnarchitectsFeatureResetPassword {
32
+ private readonly authStore;
33
+ readonly token: i0.InputSignal<string | undefined>;
34
+ readonly formConfig: i0.Signal<FormConfig>;
35
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
36
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureResetPassword, never>;
37
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureResetPassword, "anarchitects-auth-feature-reset-password", never, { "token": { "alias": "token"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
38
+ }
39
+
40
+ declare class AnarchitectsFeatureVerifyEmail {
41
+ private readonly authStore;
42
+ readonly token: i0.InputSignal<string | undefined>;
43
+ readonly formConfig: i0.Signal<FormConfig>;
44
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
45
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureVerifyEmail, never>;
46
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureVerifyEmail, "anarchitects-auth-feature-verify-email", never, { "token": { "alias": "token"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
47
+ }
48
+
49
+ declare class AnarchitectsFeatureChangePassword {
50
+ private readonly authStore;
51
+ readonly userId: i0.InputSignal<string | undefined>;
52
+ readonly formConfig: i0.WritableSignal<FormConfig>;
53
+ private resolveUserId;
54
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
55
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureChangePassword, never>;
56
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureChangePassword, "anarchitects-auth-feature-change-password", never, { "userId": { "alias": "userId"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
57
+ }
58
+
59
+ declare class AnarchitectsFeatureUpdateEmail {
60
+ private readonly authStore;
61
+ readonly userId: i0.InputSignal<string | undefined>;
62
+ readonly formConfig: i0.WritableSignal<FormConfig>;
63
+ private resolveUserId;
64
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
65
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureUpdateEmail, never>;
66
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureUpdateEmail, "anarchitects-auth-feature-update-email", never, { "userId": { "alias": "userId"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
67
+ }
68
+
69
+ declare class AnarchitectsFeatureLogout {
70
+ private readonly authStore;
71
+ readonly formConfig: i0.WritableSignal<FormConfig>;
72
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
73
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureLogout, never>;
74
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureLogout, "anarchitects-auth-feature-logout", never, {}, {}, never, never, true, never>;
75
+ }
76
+
77
+ declare class AnarchitectsFeatureRefreshTokens {
78
+ private readonly authStore;
79
+ readonly userId: i0.InputSignal<string | undefined>;
80
+ readonly formConfig: i0.WritableSignal<FormConfig>;
81
+ private resolveUserId;
82
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
83
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureRefreshTokens, never>;
84
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureRefreshTokens, "anarchitects-auth-feature-refresh-tokens", never, { "userId": { "alias": "userId"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
85
+ }
86
+
87
+ declare const policyGuard: CanMatchFn;
88
+
89
+ declare class AnarchitectsFeatureLogin {
90
+ private readonly authStore;
91
+ formConfig: i0.WritableSignal<FormConfig>;
92
+ submitForm(input: SubmissionRequestDTO): Promise<void>;
93
+ static ɵfac: i0.ɵɵFactoryDeclaration<AnarchitectsFeatureLogin, never>;
94
+ static ɵcmp: i0.ɵɵComponentDeclaration<AnarchitectsFeatureLogin, "anarchitects-auth-feature-login", never, {}, {}, never, never, true, never>;
95
+ }
96
+
97
+ export { AnarchitectsFeatureActivateUser, AnarchitectsFeatureChangePassword, AnarchitectsFeatureForgotPassword, AnarchitectsFeatureLogin, AnarchitectsFeatureLogout, AnarchitectsFeatureRefreshTokens, AnarchitectsFeatureRegister, AnarchitectsFeatureResetPassword, AnarchitectsFeatureUpdateEmail, AnarchitectsFeatureVerifyEmail, policyGuard };
@@ -0,0 +1,68 @@
1
+ import * as _ngrx_signals from '@ngrx/signals';
2
+ import * as _ngrx_signals_rxjs_interop from '@ngrx/signals/rxjs-interop';
3
+ import * as _ngrx_signals_entities from '@ngrx/signals/entities';
4
+ import * as _casl_ability from '@casl/ability';
5
+ import { PureAbility } from '@casl/ability';
6
+ import * as _angular_core from '@angular/core';
7
+ import { ChangePasswordRequestDTO, ResetPasswordRequestDTO, UpdateEmailRequestDTO, RefreshTokenRequestDTO } from '@anarchitects/auth-ts/dtos';
8
+ import { User } from '@anarchitects/auth-ts/models';
9
+
10
+ type AuthUser = Pick<User, 'id' | 'email'>;
11
+ declare const AuthStore: _angular_core.Type<{
12
+ loading: _angular_core.Signal<boolean>;
13
+ error: _angular_core.Signal<string | null>;
14
+ success: _angular_core.Signal<boolean>;
15
+ ability?: _angular_core.Signal<PureAbility<_casl_ability.AbilityTuple, unknown> | undefined> | undefined;
16
+ entityMap: _angular_core.Signal<_ngrx_signals_entities.EntityMap<AuthUser>>;
17
+ ids: _angular_core.Signal<_ngrx_signals_entities.EntityId[]>;
18
+ entities: _angular_core.Signal<AuthUser[]>;
19
+ isLoggedIn: _angular_core.Signal<boolean>;
20
+ loggedInUser: _angular_core.Signal<AuthUser>;
21
+ registerUser: _ngrx_signals_rxjs_interop.RxMethod<{
22
+ userName?: string | undefined;
23
+ email: string;
24
+ password: string;
25
+ confirmPassword: string;
26
+ }>;
27
+ activateUser: _ngrx_signals_rxjs_interop.RxMethod<{
28
+ token: string;
29
+ }>;
30
+ login: _ngrx_signals_rxjs_interop.RxMethod<{
31
+ password: string;
32
+ credential: string;
33
+ }>;
34
+ logout: _ngrx_signals_rxjs_interop.RxMethod<{
35
+ accessToken?: string | undefined;
36
+ refreshToken: string;
37
+ }>;
38
+ changePassword: _ngrx_signals_rxjs_interop.RxMethod<{
39
+ userId: string;
40
+ dto: ChangePasswordRequestDTO;
41
+ }>;
42
+ forgotPassword: _ngrx_signals_rxjs_interop.RxMethod<{
43
+ email: string;
44
+ }>;
45
+ resetPassword: _ngrx_signals_rxjs_interop.RxMethod<{
46
+ dto: ResetPasswordRequestDTO;
47
+ }>;
48
+ verifyEmail: _ngrx_signals_rxjs_interop.RxMethod<{
49
+ token: string;
50
+ }>;
51
+ updateEmail: _ngrx_signals_rxjs_interop.RxMethod<{
52
+ userId: string;
53
+ dto: UpdateEmailRequestDTO;
54
+ }>;
55
+ refreshTokens: _ngrx_signals_rxjs_interop.RxMethod<{
56
+ userId: string;
57
+ dto: RefreshTokenRequestDTO;
58
+ }>;
59
+ } & _ngrx_signals.StateSource<{
60
+ loading: boolean;
61
+ error: string | null;
62
+ success: boolean;
63
+ ability?: PureAbility | undefined;
64
+ entityMap: _ngrx_signals_entities.EntityMap<AuthUser>;
65
+ ids: _ngrx_signals_entities.EntityId[];
66
+ }>>;
67
+
68
+ export { AuthStore };
@@ -0,0 +1,17 @@
1
+ import * as _casl_ability from '@casl/ability';
2
+ import { MongoAbility } from '@casl/ability';
3
+ import { Action, Subject, PolicyRule } from '@anarchitects/auth-ts/models';
4
+
5
+ type AbilitySubject = Subject | (Record<string, unknown> & {
6
+ __caslSubjectType__?: Subject;
7
+ });
8
+ type AppAbility = MongoAbility<[
9
+ Action,
10
+ AbilitySubject
11
+ ], {
12
+ conditions: Record<string, unknown>;
13
+ }>;
14
+ declare const createAppAbility: (rules: PolicyRule[]) => MongoAbility<_casl_ability.AbilityTuple, Record<string, unknown>>;
15
+
16
+ export { createAppAbility };
17
+ export type { AppAbility };
@@ -0,0 +1,5 @@
1
+ export * from '@anarchitects/auth-angular/config';
2
+ export * from '@anarchitects/auth-angular/data-access';
3
+ export * from '@anarchitects/auth-angular/feature';
4
+ export * from '@anarchitects/auth-angular/state';
5
+ export * from '@anarchitects/auth-angular/util';
package/util/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @anarchitects/auth-angular/util
2
+
3
+ Utility layer for the Angular auth brick. Re-exported via `@anarchitects/auth-angular/util`, it centralises CASL ability helpers that are consumed by the feature and state slices.
4
+
5
+ ## Exports
6
+
7
+ - `createAppAbility(rules: PolicyRule[])`: wraps `createMongoAbility` and returns the typed `AppAbility` used throughout the auth domain.
8
+ - `AppAbility`: CASL ability type configured for `Action`/`Subject` pairs defined in `@anarchitects/auth-ts/models`.
9
+
10
+ ## Usage
11
+
12
+ ```ts
13
+ import { createAppAbility } from '@anarchitects/auth-angular/util';
14
+ import type { PolicyRule } from '@anarchitects/auth-ts/models';
15
+
16
+ const rules: PolicyRule[] = [
17
+ { action: 'read', subject: 'profile' },
18
+ { action: 'manage', subject: 'Project', conditions: { ownerId: 1 } },
19
+ ];
20
+
21
+ const ability = createAppAbility(rules);
22
+
23
+ if (ability.can('manage', 'Project')) {
24
+ // guarded feature logic
25
+ }
26
+ ```
27
+
28
+ For stateful orchestration examples, see `auth.store` in the state layer where the ability factory is integrated with the auth API responses.