@flusys/ng-auth 0.1.0-beta.3 → 1.0.0-rc

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.
@@ -1,13 +1,14 @@
1
- import { IMessageResponse, ApiResourceService, ISingleResponse, IUserProvider, IListResponse, IUserBasicInfo, ICompanyApiProvider, ICompanyBasicInfo, IUserPermissionProvider } from '@flusys/ng-shared';
1
+ import { IMessageResponse, ApiResourceService, ISingleResponse, IUserProvider, IListResponse, IUserBasicInfo, ICompanyApiProvider, ICompanyBasicInfo, IUserPermissionProvider, IAuthStateProvider, IProfileRoleInfo, IProfileActionInfo, UploadFileFn } from '@flusys/ng-shared';
2
2
  import * as rxjs from 'rxjs';
3
3
  import { Observable } from 'rxjs';
4
4
  import * as _angular_core from '@angular/core';
5
- import { Signal, Provider, OnInit } from '@angular/core';
5
+ import { Signal, Provider } from '@angular/core';
6
6
  import { HttpClient, HttpRequest, HttpHandlerFn, HttpEvent } from '@angular/common/http';
7
7
  import { CanActivateFn, Routes } from '@angular/router';
8
- import { ILayoutAuthState, ICompanyInfo as ICompanyInfo$1, IBranchInfo as IBranchInfo$1, IUserInfo as IUserInfo$1, ILayoutAuthApi } from '@flusys/ng-layout';
8
+ import { ILayoutAuthApi, ICompanyInfo as ICompanyInfo$1, IBranchInfo as IBranchInfo$1, ILayoutAuthState, IUserInfo as IUserInfo$1 } from '@flusys/ng-layout';
9
9
  import * as _angular_forms_signals from '@angular/forms/signals';
10
10
  import * as _flusys_ng_auth from '@flusys/ng-auth';
11
+ import * as _flusys_ng_core from '@flusys/ng-core';
11
12
 
12
13
  /**
13
14
  * Login Request Interface
@@ -62,6 +63,7 @@ interface IUserInfo {
62
63
  id: string;
63
64
  email: string;
64
65
  name?: string;
66
+ phone?: string | null;
65
67
  profilePictureId?: string | null;
66
68
  companyId?: string;
67
69
  branchId?: string;
@@ -134,12 +136,13 @@ interface IMeResponse {
134
136
  * Returned on successful registration
135
137
  */
136
138
  interface IRegistrationResponse {
137
- accessToken: string;
138
- refreshToken: string;
139
+ accessToken?: string;
140
+ refreshToken?: string;
139
141
  user: IUserInfo;
140
142
  company?: ICompanyInfo;
141
143
  branch?: IBranchInfo;
142
144
  companyFeatureEnabled?: boolean;
145
+ requiresEmailVerification?: boolean;
143
146
  }
144
147
  /**
145
148
  * Company Selection Response Interface
@@ -160,9 +163,21 @@ interface IRefreshTokenResponse {
160
163
  refreshToken?: string;
161
164
  }
162
165
  /**
163
- * Auth Response Type - Can be login success or company selection required
166
+ * Login Response when email verification required
167
+ */
168
+ interface ILoginRequiresEmailVerification {
169
+ requiresEmailVerification: true;
170
+ email: string;
171
+ message: string;
172
+ }
173
+ /**
174
+ * Auth Response Type - Can be login success, company selection, or email verification required
164
175
  */
165
- type AuthResponse = ILoginResponse | ICompanySelectionResponse;
176
+ type AuthResponse = ILoginResponse | ICompanySelectionResponse | ILoginRequiresEmailVerification;
177
+ /**
178
+ * Type guard to check if response requires email verification
179
+ */
180
+ declare function isEmailVerificationRequired(response: AuthResponse): response is ILoginRequiresEmailVerification;
166
181
  /**
167
182
  * Type guard to check if response requires company selection
168
183
  */
@@ -445,6 +460,16 @@ declare class AuthApiService {
445
460
  * Reset password with token
446
461
  */
447
462
  resetPassword(token: string, newPassword: string): Observable<IMessageResponse>;
463
+ /**
464
+ * Resend verification email (unauthenticated)
465
+ */
466
+ resendVerification(email: string): Observable<IMessageResponse>;
467
+ /**
468
+ * Verify email with token
469
+ * Returns IMessageResponse for existing user verification
470
+ * Returns IRegistrationResponse for pending registration completion
471
+ */
472
+ verifyEmail(token: string): Observable<IMessageResponse | IRegistrationResponse>;
448
473
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthApiService, never>;
449
474
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AuthApiService>;
450
475
  }
@@ -494,29 +519,58 @@ declare class AuthInitService {
494
519
  declare class AuthStateService {
495
520
  private readonly appConfig;
496
521
  private readonly router;
497
- readonly user: _angular_core.WritableSignal<IUserInfo | null>;
498
- readonly accessToken: _angular_core.WritableSignal<string>;
499
- readonly company: _angular_core.WritableSignal<ICompanyInfo | null>;
500
- readonly branch: _angular_core.WritableSignal<IBranchInfo | null>;
501
- readonly selectionSessionId: _angular_core.WritableSignal<string | null>;
502
- readonly availableCompanies: _angular_core.WritableSignal<ICompanyWithBranches[]>;
503
- readonly selectionExpiresAt: _angular_core.WritableSignal<Date | null>;
522
+ private readonly _user;
523
+ private readonly _accessToken;
524
+ private readonly _tokenExpiresAt;
525
+ private readonly _company;
526
+ private readonly _branch;
527
+ readonly user: _angular_core.Signal<IUserInfo | null>;
528
+ readonly accessToken: _angular_core.Signal<string>;
529
+ readonly tokenExpiresAt: _angular_core.Signal<number | null>;
530
+ readonly company: _angular_core.Signal<ICompanyInfo | null>;
531
+ readonly branch: _angular_core.Signal<IBranchInfo | null>;
532
+ private readonly _selectionSessionId;
533
+ private readonly _availableCompanies;
534
+ private readonly _selectionExpiresAt;
535
+ readonly selectionSessionId: _angular_core.Signal<string | null>;
536
+ readonly availableCompanies: _angular_core.Signal<ICompanyWithBranches[]>;
537
+ readonly selectionExpiresAt: _angular_core.Signal<Date | null>;
504
538
  readonly isAuthenticated: _angular_core.Signal<boolean>;
505
539
  readonly requiresCompanySelection: _angular_core.Signal<boolean>;
506
540
  readonly userName: _angular_core.Signal<string>;
507
541
  readonly companyName: _angular_core.Signal<string>;
508
542
  readonly branchName: _angular_core.Signal<string>;
543
+ /**
544
+ * Check if token is expired or will expire soon (within 30 seconds).
545
+ * Used to proactively refresh token before requests fail.
546
+ */
547
+ readonly isTokenExpired: _angular_core.Signal<boolean>;
548
+ /**
549
+ * Check if we need to refresh on app load (token expired but refresh cookie may exist)
550
+ */
551
+ readonly needsRefreshOnLoad: _angular_core.Signal<boolean>;
509
552
  readonly tenantId: _angular_core.Signal<string | null>;
510
553
  constructor();
511
554
  setLoginState(response: ILoginResponse): void;
512
555
  setSelectionState(response: ICompanySelectionResponse): void;
513
556
  clearSelectionState(): void;
514
557
  resetState(): void;
558
+ setUser(user: IUserInfo | null): void;
559
+ setAccessToken(token: string): void;
560
+ setCompany(company: ICompanyInfo | null): void;
561
+ setBranch(branch: IBranchInfo | null): void;
515
562
  navigateToLogin(returnUrl?: string): void;
516
563
  navigateAfterLogin(returnUrl?: string): void;
564
+ /** Validates a return URL to prevent open redirect attacks */
565
+ private isValidReturnUrl;
517
566
  getStoredCompanyId(): string | null;
518
567
  getStoredBranchId(): string | null;
519
568
  private loadFromStorage;
569
+ /**
570
+ * Decode JWT expiry without verification (client-side only).
571
+ * Returns expiry timestamp in milliseconds.
572
+ */
573
+ private decodeTokenExpiry;
520
574
  private store;
521
575
  private get;
522
576
  private remove;
@@ -602,12 +656,18 @@ declare class CompanyApiService extends ApiResourceService<ICreateCompanyRequest
602
656
  * Manages token refresh state in a request-safe manner for SSR environments.
603
657
  * Replaces module-level state that would be shared across requests in SSR.
604
658
  *
659
+ * NOTE: Uses BehaviorSubject intentionally for RxJS interoperability.
660
+ * The HTTP interceptor needs to queue concurrent requests and have them
661
+ * wait for the new token via Observable subscription. This is a valid
662
+ * pattern that signals cannot replicate directly (no multi-subscriber
663
+ * async coordination). Signal is used for the boolean flag only.
664
+ *
605
665
  * @example
606
666
  * ```typescript
607
667
  * const refreshState = inject(TokenRefreshStateService);
608
668
  *
609
669
  * if (refreshState.isRefreshing()) {
610
- * // Queue request
670
+ * // Queue request via refreshTokenSubject$
611
671
  * } else {
612
672
  * refreshState.startRefresh();
613
673
  * // Perform refresh
@@ -688,11 +748,11 @@ declare class UserApiService extends ApiResourceService<ICreateUserRequest | IUp
688
748
  * Handles user-company and user-branch permission assignments.
689
749
  * Uses batch operations for efficient permission management.
690
750
  *
691
- * Backend Endpoints:
751
+ * Backend Endpoints (POST-only RPC):
692
752
  * - POST /administration/permissions/user-company/assign - Batch assign/revoke company permissions
693
- * - GET /administration/permissions/user-company?userId=xxx - Get user's companies
753
+ * - POST /administration/permissions/get-user-company - Get user's companies
694
754
  * - POST /administration/permissions/user-branch/assign - Batch assign/revoke branch permissions
695
- * - GET /administration/permissions/user-branch?userId=xxx - Get user's branches
755
+ * - POST /administration/permissions/get-user-branch - Get user's branches
696
756
  */
697
757
  declare class UserPermissionApiService {
698
758
  private readonly appConfig;
@@ -848,34 +908,28 @@ declare const guestGuard: CanActivateFn;
848
908
  declare const companyFeatureGuard: CanActivateFn;
849
909
 
850
910
  /**
851
- * Auth Interceptor
852
- * Adds Authorization header and tenant header to HTTP requests.
853
- *
854
- * - Adds Bearer token for authenticated requests (including /auth/me)
855
- * - Adds tenant header for multi-tenant mode
856
- * - Adds withCredentials for auth endpoints (cookies)
857
- *
858
- * @example
859
- * ```typescript
860
- * // In app.config.ts
861
- * provideHttpClient(
862
- * withFetch(),
863
- * withInterceptors([authInterceptor, tokenRefreshInterceptor])
864
- * )
865
- * ```
911
+ * Auth Interceptor - Adds auth headers and cookie credentials to requests
866
912
  */
867
913
  declare function authInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>;
868
914
 
869
915
  /**
870
916
  * Token Refresh Interceptor
871
- * Handles 401 errors by refreshing the access token.
917
+ * Handles token refresh both proactively and reactively.
918
+ *
919
+ * PROACTIVE REFRESH:
920
+ * - Checks token expiry BEFORE making requests
921
+ * - Refreshes token if expired or expiring soon (within 30 seconds)
922
+ * - Prevents unnecessary 401 failures
872
923
  *
873
- * - Intercepts 401 Unauthorized responses
874
- * - Calls refresh token endpoint
875
- * - Retries failed request with new token
924
+ * REACTIVE REFRESH:
925
+ * - Still handles 401 errors as fallback
876
926
  * - Queues concurrent requests during refresh
877
927
  * - Redirects to login on refresh failure
878
- * - SSR-safe: Uses injectable service instead of module-level state
928
+ *
929
+ * SECURITY:
930
+ * - Token kept in memory only (not localStorage)
931
+ * - Uses HTTP-only refresh token cookie
932
+ * - SSR-safe: Uses injectable service
879
933
  *
880
934
  * @example
881
935
  * ```typescript
@@ -901,6 +955,11 @@ declare const AUTH_ROUTES: Routes;
901
955
  * Uses tabbed interface - all under /administration with child routes
902
956
  */
903
957
  declare const ADMINISTRATION_ROUTES: Routes;
958
+ /**
959
+ * Profile Routes Configuration
960
+ * Protected route for user profile management
961
+ */
962
+ declare const PROFILE_ROUTES: Routes;
904
963
 
905
964
  /**
906
965
  * Auth Layout State Adapter
@@ -992,6 +1051,7 @@ declare class AuthUserProviderAdapter implements IUserProvider {
992
1051
  search?: string;
993
1052
  companyId?: string;
994
1053
  branchId?: string;
1054
+ isActive?: boolean;
995
1055
  [key: string]: any;
996
1056
  }): Observable<IListResponse<IUserBasicInfo>>;
997
1057
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthUserProviderAdapter, never>;
@@ -1040,6 +1100,39 @@ declare class AuthUserPermissionProviderAdapter implements IUserPermissionProvid
1040
1100
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<AuthUserPermissionProviderAdapter>;
1041
1101
  }
1042
1102
 
1103
+ /**
1104
+ * Auth State Provider Adapter
1105
+ *
1106
+ * Implements IAuthStateProvider interface from ng-shared using auth services from ng-auth.
1107
+ * This allows feature packages (form-builder, etc.) to check auth state without
1108
+ * depending on ng-auth directly.
1109
+ *
1110
+ * @example
1111
+ * // In app.config.ts
1112
+ * providers: [
1113
+ * { provide: AUTH_STATE_PROVIDER, useClass: AuthStateProviderAdapter }
1114
+ * ]
1115
+ *
1116
+ * // In form-builder component
1117
+ * private readonly authStateProvider = inject(AUTH_STATE_PROVIDER);
1118
+ * const isLoggedIn = this.authStateProvider.isAuthenticated();
1119
+ */
1120
+ declare class AuthStateProviderAdapter implements IAuthStateProvider {
1121
+ private readonly authState;
1122
+ private readonly authInit;
1123
+ /**
1124
+ * Signal indicating if user is currently authenticated
1125
+ */
1126
+ get isAuthenticated(): Signal<boolean>;
1127
+ /**
1128
+ * Initialize auth state (restore session from cookies/storage)
1129
+ * Returns Observable<void> that completes when initialization is done
1130
+ */
1131
+ initialize(): Observable<void>;
1132
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AuthStateProviderAdapter, never>;
1133
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<AuthStateProviderAdapter>;
1134
+ }
1135
+
1043
1136
  /**
1044
1137
  * Provides auth layout integration for ng-layout.
1045
1138
  * Call this in your app.config.ts to integrate ng-auth with ng-layout.
@@ -1100,6 +1193,10 @@ declare const AUTH_ENDPOINTS: {
1100
1193
  readonly REGISTER: "/auth/register";
1101
1194
  readonly SELECT: "/auth/select";
1102
1195
  readonly SWITCH_COMPANY: "/auth/switch-company";
1196
+ readonly VERIFY_EMAIL: "/auth/verify-email";
1197
+ readonly FORGOT_PASSWORD: "/auth/forgot-password";
1198
+ readonly RESET_PASSWORD: "/auth/reset-password";
1199
+ readonly RESEND_VERIFICATION: "/auth/resend-verification";
1103
1200
  };
1104
1201
  /**
1105
1202
  * Check if a URL is an auth-related endpoint
@@ -1153,13 +1250,15 @@ interface IBranchFormModel {
1153
1250
  * Handles creating and editing branches.
1154
1251
  * Defaults to current company context.
1155
1252
  */
1156
- declare class BranchFormComponent implements OnInit {
1253
+ declare class BranchFormComponent {
1157
1254
  private readonly router;
1158
1255
  private readonly route;
1159
1256
  private readonly messageService;
1160
1257
  private readonly branchService;
1161
1258
  private readonly companyService;
1162
1259
  private readonly authState;
1260
+ private readonly routeParams;
1261
+ private readonly queryParams;
1163
1262
  /** Loading state */
1164
1263
  readonly isLoading: _angular_core.WritableSignal<boolean>;
1165
1264
  /** Existing branch data when editing */
@@ -1174,7 +1273,7 @@ declare class BranchFormComponent implements OnInit {
1174
1273
  readonly branchForm: _angular_forms_signals.FieldTree<IBranchFormModel, string | number>;
1175
1274
  /** Check if form is valid */
1176
1275
  readonly isFormValid: _angular_core.Signal<boolean>;
1177
- ngOnInit(): void;
1276
+ constructor();
1178
1277
  loadBranch(id: string): Promise<void>;
1179
1278
  generateSlug(): void;
1180
1279
  onSubmit(): Promise<void>;
@@ -1188,7 +1287,13 @@ declare class BranchFormComponent implements OnInit {
1188
1287
  * Displays a list of branches for a company with CRUD operations.
1189
1288
  * Defaults to current company context.
1190
1289
  */
1191
- declare class BranchListComponent implements OnInit {
1290
+ declare class BranchListComponent {
1291
+ readonly BRANCH_PERMISSIONS: {
1292
+ readonly CREATE: "branch.create";
1293
+ readonly READ: "branch.read";
1294
+ readonly UPDATE: "branch.update";
1295
+ readonly DELETE: "branch.delete";
1296
+ };
1192
1297
  private readonly router;
1193
1298
  private readonly route;
1194
1299
  private readonly messageService;
@@ -1196,8 +1301,10 @@ declare class BranchListComponent implements OnInit {
1196
1301
  private readonly branchService;
1197
1302
  private readonly companyService;
1198
1303
  private readonly authState;
1199
- /** Selected company ID */
1200
- selectedCompanyId: string | null;
1304
+ private readonly queryParamMap;
1305
+ private initialized;
1306
+ /** Selected company ID (signal for zoneless change detection) */
1307
+ readonly selectedCompanyId: _angular_core.WritableSignal<string | null>;
1201
1308
  /** Companies list for dropdown */
1202
1309
  readonly companies: _angular_core.Signal<_flusys_ng_auth.ICompany[]>;
1203
1310
  /** Branches from service */
@@ -1206,7 +1313,7 @@ declare class BranchListComponent implements OnInit {
1206
1313
  readonly isLoading: _angular_core.Signal<boolean>;
1207
1314
  /** Total count from service */
1208
1315
  readonly total: _angular_core.Signal<number>;
1209
- ngOnInit(): void;
1316
+ constructor();
1210
1317
  loadBranches(): void;
1211
1318
  onCompanyChange(): void;
1212
1319
  onLazyLoad(event: {
@@ -1234,11 +1341,12 @@ interface ICompanyFormModel$1 {
1234
1341
  * Company Form Component
1235
1342
  * Handles creating and editing companies.
1236
1343
  */
1237
- declare class CompanyFormComponent implements OnInit {
1344
+ declare class CompanyFormComponent {
1238
1345
  private readonly router;
1239
1346
  private readonly route;
1240
1347
  private readonly messageService;
1241
1348
  private readonly companyService;
1349
+ private readonly routeParams;
1242
1350
  /** Loading state */
1243
1351
  readonly isLoading: _angular_core.WritableSignal<boolean>;
1244
1352
  /** Existing company data when editing */
@@ -1251,7 +1359,7 @@ declare class CompanyFormComponent implements OnInit {
1251
1359
  readonly companyForm: _angular_forms_signals.FieldTree<ICompanyFormModel$1, string | number>;
1252
1360
  /** Check if form is valid */
1253
1361
  readonly isFormValid: _angular_core.Signal<boolean>;
1254
- ngOnInit(): void;
1362
+ constructor();
1255
1363
  loadCompany(id: string): Promise<void>;
1256
1364
  generateSlug(): void;
1257
1365
  onSubmit(): Promise<void>;
@@ -1265,7 +1373,19 @@ declare class CompanyFormComponent implements OnInit {
1265
1373
  * Displays a list of companies with CRUD operations.
1266
1374
  * Only visible when company feature is enabled.
1267
1375
  */
1268
- declare class CompanyListComponent implements OnInit {
1376
+ declare class CompanyListComponent {
1377
+ readonly COMPANY_PERMISSIONS: {
1378
+ readonly CREATE: "company.create";
1379
+ readonly READ: "company.read";
1380
+ readonly UPDATE: "company.update";
1381
+ readonly DELETE: "company.delete";
1382
+ };
1383
+ readonly BRANCH_PERMISSIONS: {
1384
+ readonly CREATE: "branch.create";
1385
+ readonly READ: "branch.read";
1386
+ readonly UPDATE: "branch.update";
1387
+ readonly DELETE: "branch.delete";
1388
+ };
1269
1389
  private readonly router;
1270
1390
  private readonly messageService;
1271
1391
  private readonly confirmationService;
@@ -1276,7 +1396,6 @@ declare class CompanyListComponent implements OnInit {
1276
1396
  readonly isLoading: _angular_core.Signal<boolean>;
1277
1397
  /** Total count from service */
1278
1398
  readonly total: _angular_core.Signal<number>;
1279
- ngOnInit(): void;
1280
1399
  loadCompanies(): void;
1281
1400
  onLazyLoad(event: {
1282
1401
  first?: number | null;
@@ -1290,6 +1409,25 @@ declare class CompanyListComponent implements OnInit {
1290
1409
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<CompanyListComponent, "lib-company-list", never, {}, {}, never, never, true, never>;
1291
1410
  }
1292
1411
 
1412
+ interface IForgotPasswordFormModel {
1413
+ email: string;
1414
+ }
1415
+ declare class ForgotPasswordPageComponent {
1416
+ private readonly destroyRef;
1417
+ private readonly messageService;
1418
+ private readonly authApi;
1419
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
1420
+ readonly emailSent: _angular_core.WritableSignal<boolean>;
1421
+ readonly submittedEmail: _angular_core.WritableSignal<string>;
1422
+ readonly formModel: _angular_core.WritableSignal<IForgotPasswordFormModel>;
1423
+ readonly forgotForm: _angular_forms_signals.FieldTree<IForgotPasswordFormModel, string | number>;
1424
+ readonly isFormValid: _angular_core.Signal<boolean>;
1425
+ onSubmit(): void;
1426
+ resetForm(): void;
1427
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForgotPasswordPageComponent, never>;
1428
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ForgotPasswordPageComponent, "lib-forgot-password-page", never, {}, {}, never, never, true, never>;
1429
+ }
1430
+
1293
1431
  /** Login form model interface */
1294
1432
  interface ILoginFormModel {
1295
1433
  email: string;
@@ -1302,25 +1440,23 @@ interface ISelectionFormModel {
1302
1440
  branchId: string;
1303
1441
  rememberSelection: boolean;
1304
1442
  }
1305
- type LoginStep = 'credentials' | 'company-selection';
1443
+ type LoginStep = 'credentials' | 'company-selection' | 'email-verification';
1306
1444
  /**
1307
1445
  * Login Page Component
1308
1446
  * Multi-step authentication flow:
1309
1447
  * - Step 1: Email/Password credentials
1310
1448
  * - Step 2: Company/Branch selection (when company feature enabled and user has multiple)
1311
1449
  */
1312
- declare class LoginPageComponent implements OnInit {
1450
+ declare class LoginPageComponent {
1313
1451
  private readonly destroyRef;
1314
1452
  private readonly appConfig;
1315
1453
  private readonly messageService;
1316
1454
  private readonly authApi;
1317
1455
  private readonly authState;
1318
- /** Return URL after successful login */
1319
1456
  readonly returnUrl: _angular_core.InputSignal<string>;
1320
- /** Current step in login flow */
1321
1457
  readonly currentStep: _angular_core.WritableSignal<LoginStep>;
1322
- /** Loading state */
1323
1458
  readonly isLoading: _angular_core.WritableSignal<boolean>;
1459
+ readonly unverifiedEmail: _angular_core.WritableSignal<string>;
1324
1460
  /** Login form model */
1325
1461
  readonly loginFormModel: _angular_core.WritableSignal<ILoginFormModel>;
1326
1462
  /** Login form with validation schema */
@@ -1343,18 +1479,105 @@ declare class LoginPageComponent implements OnInit {
1343
1479
  readonly userName: _angular_core.WritableSignal<string>;
1344
1480
  /** Branches for selected company */
1345
1481
  readonly branches: _angular_core.Signal<IBranchSelectionInfo[]>;
1346
- ngOnInit(): void;
1482
+ constructor();
1483
+ /**
1484
+ * Restores pending company selection state from auth service.
1485
+ * Called when user refreshes page during Step 2 of login flow.
1486
+ */
1487
+ private restorePendingSelectionState;
1347
1488
  onSubmit(): void;
1348
1489
  /** Handle company selection change */
1349
1490
  onCompanyChange(): void;
1350
1491
  onSelectCompany(): void;
1351
1492
  goBackToCredentials(): void;
1493
+ onResendVerification(): void;
1352
1494
  private autoSelectIfSingle;
1353
1495
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<LoginPageComponent, never>;
1354
1496
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<LoginPageComponent, "lib-login-page", never, { "returnUrl": { "alias": "returnUrl"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1355
1497
  }
1356
1498
 
1357
- /** User registration form model */
1499
+ /** Profile form model */
1500
+ interface IProfileFormModel {
1501
+ name: string;
1502
+ phone: string;
1503
+ }
1504
+ /** Password form model */
1505
+ interface IPasswordFormModel {
1506
+ currentPassword: string;
1507
+ newPassword: string;
1508
+ confirmPassword: string;
1509
+ }
1510
+ /**
1511
+ * Profile Page Component
1512
+ *
1513
+ * Allows users to view and update their profile information.
1514
+ * Features:
1515
+ * - Update name, phone, profile picture (if storage enabled)
1516
+ * - View company/branch info (read-only, if company feature enabled)
1517
+ * - View roles/actions (read-only, if IAM enabled via optional injection)
1518
+ *
1519
+ * Package Independence:
1520
+ * - Uses PROFILE_UPLOAD_PROVIDER (optional) for storage functionality
1521
+ * - Uses PROFILE_PERMISSION_PROVIDER (optional) for IAM functionality
1522
+ * - No direct imports from ng-storage or ng-iam
1523
+ */
1524
+ declare class ProfilePageComponent {
1525
+ private readonly destroyRef;
1526
+ private readonly appConfig;
1527
+ private readonly messageService;
1528
+ private readonly authState;
1529
+ private readonly userService;
1530
+ private readonly authApiService;
1531
+ private readonly fileUrlService;
1532
+ private readonly uploadProvider;
1533
+ private readonly permissionProvider;
1534
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
1535
+ readonly isLoadingPermissions: _angular_core.WritableSignal<boolean>;
1536
+ private readonly _profilePictureUrl;
1537
+ readonly profilePictureUrl: _angular_core.Signal<string | null>;
1538
+ private readonly _userRoles;
1539
+ readonly userRoles: _angular_core.Signal<IProfileRoleInfo[]>;
1540
+ private readonly _userActions;
1541
+ readonly userActions: _angular_core.Signal<IProfileActionInfo[]>;
1542
+ readonly userEmail: _angular_core.Signal<string>;
1543
+ readonly userName: _angular_core.Signal<string>;
1544
+ readonly userInitials: _angular_core.Signal<string>;
1545
+ readonly companyName: _angular_core.Signal<string>;
1546
+ readonly branchName: _angular_core.Signal<string>;
1547
+ readonly showUploadSection: _angular_core.Signal<boolean>;
1548
+ readonly showCompanySection: _angular_core.Signal<boolean>;
1549
+ readonly showPermissionsSection: _angular_core.Signal<boolean>;
1550
+ readonly permissionMode: _angular_core.Signal<_flusys_ng_core.PermissionMode>;
1551
+ readonly showRoles: _angular_core.Signal<boolean>;
1552
+ readonly showActions: _angular_core.Signal<boolean>;
1553
+ readonly showBottomRow: _angular_core.Signal<boolean>;
1554
+ readonly formModel: _angular_core.WritableSignal<IProfileFormModel>;
1555
+ readonly formTree: _angular_forms_signals.FieldTree<IProfileFormModel, string | number>;
1556
+ readonly isFormValid: _angular_core.Signal<boolean>;
1557
+ readonly passwordModel: _angular_core.WritableSignal<IPasswordFormModel>;
1558
+ readonly isPasswordLoading: _angular_core.WritableSignal<boolean>;
1559
+ readonly isPasswordFormValid: _angular_core.Signal<boolean>;
1560
+ readonly passwordsMatch: _angular_core.Signal<boolean>;
1561
+ readonly uploadFileFn: UploadFileFn;
1562
+ /** Map upload result to IUploadedFile format */
1563
+ private mapUploadResultToUploadedFile;
1564
+ constructor();
1565
+ private loadUserData;
1566
+ private loadPermissions;
1567
+ onProfilePictureUploaded(file: {
1568
+ id?: string;
1569
+ name: string;
1570
+ key: string;
1571
+ size: number;
1572
+ contentType: string;
1573
+ }): void;
1574
+ onSubmit(): void;
1575
+ updatePasswordField(field: keyof IPasswordFormModel, value: string): void;
1576
+ onChangePassword(): void;
1577
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProfilePageComponent, never>;
1578
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ProfilePageComponent, "lib-profile-page", never, {}, {}, never, never, true, never>;
1579
+ }
1580
+
1358
1581
  interface IUserFormModel$1 {
1359
1582
  name: string;
1360
1583
  email: string;
@@ -1362,7 +1585,6 @@ interface IUserFormModel$1 {
1362
1585
  confirmPassword: string;
1363
1586
  phone: string;
1364
1587
  }
1365
- /** Company form model */
1366
1588
  interface ICompanyFormModel {
1367
1589
  createNewCompany: boolean;
1368
1590
  companySlug: string;
@@ -1371,43 +1593,57 @@ interface ICompanyFormModel {
1371
1593
  newCompanyPhone: string;
1372
1594
  newCompanyAddress: string;
1373
1595
  }
1374
- /**
1375
- * Registration Page Component
1376
- * Handles user registration with optional company creation
1377
- * Adapts UI based on company feature configuration
1378
- */
1379
- declare class RegisterPageComponent implements OnInit {
1596
+ declare class RegisterPageComponent {
1380
1597
  private readonly destroyRef;
1381
1598
  private readonly appConfig;
1382
1599
  private readonly messageService;
1383
1600
  private readonly authApi;
1384
1601
  private readonly authState;
1385
1602
  private readonly route;
1386
- /** Return URL after successful registration */
1603
+ private readonly router;
1604
+ private readonly queryParamMap;
1605
+ private companySlugInitialized;
1387
1606
  readonly returnUrl: _angular_core.InputSignal<string>;
1388
- /** Loading state */
1389
1607
  readonly isLoading: _angular_core.WritableSignal<boolean>;
1390
- /** Whether company feature is enabled */
1391
1608
  readonly companyFeatureEnabled: _angular_core.Signal<boolean>;
1392
- /** User form model */
1393
1609
  readonly userFormModel: _angular_core.WritableSignal<IUserFormModel$1>;
1394
- /** User form with validation schema */
1395
1610
  readonly userForm: _angular_forms_signals.FieldTree<IUserFormModel$1, string | number>;
1396
- /** Company form model */
1397
1611
  readonly companyFormModel: _angular_core.WritableSignal<ICompanyFormModel>;
1398
- /** Company form with conditional validation schema */
1399
1612
  readonly companyForm: _angular_forms_signals.FieldTree<ICompanyFormModel, string | number>;
1400
- ngOnInit(): void;
1401
- /** Check if passwords match */
1402
1613
  readonly passwordsMatch: _angular_core.Signal<boolean>;
1403
- /** Check if form is valid */
1404
1614
  readonly isFormValid: _angular_core.Signal<boolean>;
1615
+ constructor();
1405
1616
  onCreateCompanyToggle(): void;
1406
1617
  onSubmit(): void;
1407
1618
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RegisterPageComponent, never>;
1408
1619
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<RegisterPageComponent, "lib-register-page", never, { "returnUrl": { "alias": "returnUrl"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1409
1620
  }
1410
1621
 
1622
+ interface IResetPasswordFormModel {
1623
+ newPassword: string;
1624
+ confirmPassword: string;
1625
+ }
1626
+ type PageState$1 = 'form' | 'success' | 'invalid-token';
1627
+ declare class ResetPasswordPageComponent {
1628
+ private readonly destroyRef;
1629
+ private readonly route;
1630
+ private readonly messageService;
1631
+ private readonly authApi;
1632
+ private readonly queryParams;
1633
+ private tokenInitialized;
1634
+ private token;
1635
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
1636
+ readonly pageState: _angular_core.WritableSignal<PageState$1>;
1637
+ readonly formModel: _angular_core.WritableSignal<IResetPasswordFormModel>;
1638
+ readonly resetForm: _angular_forms_signals.FieldTree<IResetPasswordFormModel, string | number>;
1639
+ readonly passwordMismatch: _angular_core.Signal<boolean>;
1640
+ readonly canSubmit: _angular_core.Signal<boolean>;
1641
+ constructor();
1642
+ onSubmit(): void;
1643
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ResetPasswordPageComponent, never>;
1644
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ResetPasswordPageComponent, "lib-reset-password-page", never, {}, {}, never, never, true, never>;
1645
+ }
1646
+
1411
1647
  /** User form model interface */
1412
1648
  interface IUserFormModel {
1413
1649
  name: string;
@@ -1422,7 +1658,7 @@ interface IUserFormModel {
1422
1658
  * Handles creating and editing users.
1423
1659
  * When company feature is enabled, automatically assigns new users to current company/branch.
1424
1660
  */
1425
- declare class UserFormComponent implements OnInit {
1661
+ declare class UserFormComponent {
1426
1662
  private readonly destroyRef;
1427
1663
  private readonly router;
1428
1664
  private readonly route;
@@ -1431,6 +1667,8 @@ declare class UserFormComponent implements OnInit {
1431
1667
  private readonly userService;
1432
1668
  private readonly permissionService;
1433
1669
  private readonly authState;
1670
+ private readonly routeParams;
1671
+ private userLoadTriggered;
1434
1672
  /** Loading state */
1435
1673
  readonly isLoading: _angular_core.WritableSignal<boolean>;
1436
1674
  /** Existing user data when editing */
@@ -1449,7 +1687,7 @@ declare class UserFormComponent implements OnInit {
1449
1687
  readonly formTree: _angular_forms_signals.FieldTree<IUserFormModel, string | number>;
1450
1688
  /** Check if form is valid */
1451
1689
  readonly isFormValid: _angular_core.Signal<boolean>;
1452
- ngOnInit(): void;
1690
+ constructor();
1453
1691
  loadUser(id: string): void;
1454
1692
  onSubmit(): void;
1455
1693
  /**
@@ -1465,7 +1703,13 @@ declare class UserFormComponent implements OnInit {
1465
1703
  * User List Component
1466
1704
  * Displays a list of users with CRUD operations.
1467
1705
  */
1468
- declare class UserListComponent implements OnInit {
1706
+ declare class UserListComponent {
1707
+ readonly USER_PERMISSIONS: {
1708
+ readonly CREATE: "user.create";
1709
+ readonly READ: "user.read";
1710
+ readonly UPDATE: "user.update";
1711
+ readonly DELETE: "user.delete";
1712
+ };
1469
1713
  private readonly router;
1470
1714
  private readonly appConfig;
1471
1715
  private readonly messageService;
@@ -1484,7 +1728,6 @@ declare class UserListComponent implements OnInit {
1484
1728
  readonly showBranchDialog: _angular_core.WritableSignal<boolean>;
1485
1729
  /** Selected user for permission management */
1486
1730
  readonly selectedUser: _angular_core.WritableSignal<IUser | null>;
1487
- ngOnInit(): void;
1488
1731
  loadUsers(): void;
1489
1732
  onLazyLoad(event: {
1490
1733
  first?: number | null;
@@ -1499,6 +1742,36 @@ declare class UserListComponent implements OnInit {
1499
1742
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserListComponent, "lib-user-list", never, {}, {}, never, never, true, never>;
1500
1743
  }
1501
1744
 
1745
+ interface IResendFormModel {
1746
+ email: string;
1747
+ }
1748
+ type PageState = 'verifying' | 'success' | 'invalid-token' | 'resend';
1749
+ declare class VerifyEmailPageComponent {
1750
+ private readonly platformId;
1751
+ private readonly transferState;
1752
+ private readonly destroyRef;
1753
+ private readonly route;
1754
+ private readonly messageService;
1755
+ private readonly authApi;
1756
+ private readonly queryParams;
1757
+ private verificationTriggered;
1758
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
1759
+ readonly pageState: _angular_core.WritableSignal<PageState>;
1760
+ readonly resendSuccess: _angular_core.WritableSignal<boolean>;
1761
+ readonly submittedEmail: _angular_core.WritableSignal<string>;
1762
+ readonly resendFormModel: _angular_core.WritableSignal<IResendFormModel>;
1763
+ readonly resendForm: _angular_forms_signals.FieldTree<IResendFormModel, string | number>;
1764
+ readonly isResendFormValid: _angular_core.Signal<boolean>;
1765
+ constructor();
1766
+ private verifyEmail;
1767
+ private handleVerificationResult;
1768
+ showResendForm(): void;
1769
+ onResend(): void;
1770
+ private handleResendComplete;
1771
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<VerifyEmailPageComponent, never>;
1772
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<VerifyEmailPageComponent, "lib-verify-email-page", never, {}, {}, never, never, true, never>;
1773
+ }
1774
+
1502
1775
  /**
1503
1776
  * User Branch Permission Dialog
1504
1777
  *
@@ -1594,5 +1867,5 @@ interface CompanyWithAssignment extends ICompany {
1594
1867
  isAssigned: boolean;
1595
1868
  }
1596
1869
 
1597
- export { ADMINISTRATION_ROUTES, AUTH_ENDPOINTS, AUTH_ROUTES, AdministrationPageComponent, AuthApiService, AuthCompanyApiProviderAdapter, AuthInitService, AuthLayoutApiAdapter, AuthLayoutStateAdapter, AuthStateService, AuthUserPermissionProviderAdapter, AuthUserProviderAdapter, BranchApiService, BranchFormComponent, BranchListComponent, CompanyApiService, CompanyFormComponent, CompanyListComponent, LoginPageComponent, RegisterPageComponent, TokenRefreshStateService, UserApiService, UserBranchPermissionDialogComponent, UserCompanyPermissionDialogComponent, UserFormComponent, UserListComponent, UserPermissionApiService, authGuard, authInterceptor, companyFeatureGuard, guestGuard, isAuthEndpoint, isCompanySelectionResponse, isEndpoint, isLoginResponse, provideAuthLayoutIntegration, provideAuthProviders, tokenRefreshInterceptor };
1598
- export type { AuthResponse, IAssignUserBranchRequest, IAssignUserCompanyRequest, IBatchOperationResponse, IBranch, IBranchInfo, IBranchSelectionInfo, IChangePasswordRequest, ICompany, ICompanyInfo, ICompanySelectionResponse, ICompanyWithBranches, ICreateBranchRequest, ICreateCompanyRequest, ICreateUserRequest, ILoginRequest, ILoginResponse, IMeResponse, IPermissionItem, IRefreshTokenResponse, IRegistrationRequest, IRegistrationResponse, ISelectRequest, ISwitchCompanyRequest, IUpdateBranchRequest, IUpdateCompanyRequest, IUpdateUserRequest, IUser, IUserBranchPermission, IUserBranchesResponse, IUserCompaniesResponse, IUserCompanyPermission, IUserInfo };
1870
+ export { ADMINISTRATION_ROUTES, AUTH_ENDPOINTS, AUTH_ROUTES, AdministrationPageComponent, AuthApiService, AuthCompanyApiProviderAdapter, AuthInitService, AuthLayoutApiAdapter, AuthLayoutStateAdapter, AuthStateProviderAdapter, AuthStateService, AuthUserPermissionProviderAdapter, AuthUserProviderAdapter, BranchApiService, BranchFormComponent, BranchListComponent, CompanyApiService, CompanyFormComponent, CompanyListComponent, ForgotPasswordPageComponent, LoginPageComponent, PROFILE_ROUTES, ProfilePageComponent, RegisterPageComponent, ResetPasswordPageComponent, TokenRefreshStateService, UserApiService, UserBranchPermissionDialogComponent, UserCompanyPermissionDialogComponent, UserFormComponent, UserListComponent, UserPermissionApiService, VerifyEmailPageComponent, authGuard, authInterceptor, companyFeatureGuard, guestGuard, isAuthEndpoint, isCompanySelectionResponse, isEmailVerificationRequired, isEndpoint, isLoginResponse, provideAuthLayoutIntegration, provideAuthProviders, tokenRefreshInterceptor };
1871
+ export type { AuthResponse, IAssignUserBranchRequest, IAssignUserCompanyRequest, IBatchOperationResponse, IBranch, IBranchInfo, IBranchSelectionInfo, IChangePasswordRequest, ICompany, ICompanyInfo, ICompanySelectionResponse, ICompanyWithBranches, ICreateBranchRequest, ICreateCompanyRequest, ICreateUserRequest, ILoginRequest, ILoginRequiresEmailVerification, ILoginResponse, IMeResponse, IPermissionItem, IRefreshTokenResponse, IRegistrationRequest, IRegistrationResponse, ISelectRequest, ISwitchCompanyRequest, IUpdateBranchRequest, IUpdateCompanyRequest, IUpdateUserRequest, IUser, IUserBranchPermission, IUserBranchesResponse, IUserCompaniesResponse, IUserCompanyPermission, IUserInfo };