@flusys/ng-auth 9.1.0 → 9.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/fesm2022/flusys-ng-auth-administration-page.component-DmN4KqiR.mjs +146 -0
- package/fesm2022/flusys-ng-auth-administration-page.component-DmN4KqiR.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-branch-form.component-Df_sMC2G.mjs +743 -0
- package/fesm2022/flusys-ng-auth-branch-form.component-Df_sMC2G.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-branch-list.component-CWat6QWN.mjs +775 -0
- package/fesm2022/flusys-ng-auth-branch-list.component-CWat6QWN.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-company-form.component-BvZ4Pn8j.mjs +198 -0
- package/fesm2022/flusys-ng-auth-company-form.component-BvZ4Pn8j.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-company-list.component-Corh9AIh.mjs +241 -0
- package/fesm2022/flusys-ng-auth-company-list.component-Corh9AIh.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-extension-order.util-2XWSLqii.mjs +6 -0
- package/fesm2022/flusys-ng-auth-extension-order.util-2XWSLqii.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-forgot-password-page.component-BRTVZPX6.mjs +384 -0
- package/fesm2022/flusys-ng-auth-forgot-password-page.component-BRTVZPX6.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-login-page.component-DQl52Qau.mjs +1074 -0
- package/fesm2022/flusys-ng-auth-login-page.component-DQl52Qau.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-profile-page.component-b-8rPEXQ.mjs +1792 -0
- package/fesm2022/flusys-ng-auth-profile-page.component-b-8rPEXQ.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-register-page.component-D99y1jiA.mjs +1513 -0
- package/fesm2022/flusys-ng-auth-register-page.component-D99y1jiA.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-reset-password-page.component-C0tN_AW1.mjs +538 -0
- package/fesm2022/flusys-ng-auth-reset-password-page.component-C0tN_AW1.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-social-callback-page.component-gTD7_LJY.mjs +217 -0
- package/fesm2022/flusys-ng-auth-social-callback-page.component-gTD7_LJY.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-social-config-page.component-DpGmcb9n.mjs +541 -0
- package/fesm2022/flusys-ng-auth-social-config-page.component-DpGmcb9n.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-user-form.component-CM9UYc0q.mjs +1171 -0
- package/fesm2022/flusys-ng-auth-user-form.component-CM9UYc0q.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-user-list.component-Bew7gz-H.mjs +1046 -0
- package/fesm2022/flusys-ng-auth-user-list.component-Bew7gz-H.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth-verify-email-page.component-DB9iKvt3.mjs +545 -0
- package/fesm2022/flusys-ng-auth-verify-email-page.component-DB9iKvt3.mjs.map +1 -0
- package/fesm2022/flusys-ng-auth.mjs +3030 -10735
- package/fesm2022/flusys-ng-auth.mjs.map +1 -1
- package/package.json +5 -5
- package/types/flusys-ng-auth.d.ts +978 -1558
package/README.md
CHANGED
|
@@ -58,6 +58,8 @@ export const routes: Routes = [
|
|
|
58
58
|
];
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
**Branch hierarchy:** branches nest via `parentId`. The branch list renders a tree (`f-treetable`, all branches of the selected company loaded at once, search keeps ancestors of matches). Each row has an "Add Sub-branch" action (`/administration/branch/new?companyId=…&parentId=…`), and deleting a branch with sub-branches warns how many will be deleted with it. The backend extends a delete or soft delete to every descendant, so the readonly check, permission cleanup, IAM sync and domain events cover them too; restore does not cascade. The branch form picks the parent via `f-treeselect`, scoped to the company and excluding the branch itself and its descendants; a `parentId` query param prefills it. The login company/branch selection step, the topbar company/branch switcher and the IAM user role/action selectors also pick the branch via `f-treeselect`, and the Manage Branch Permissions dialog lists its branch checkboxes as an indented tree (each branch is still assigned or revoked on its own; checking a parent does not check its children). The login selection response, `get-my-company-branches` and `permissions/get-user-branch` carry `parentId`, `serial` and `displayParentId` (the nearest ancestor that is also granted, computed by the backend so ungranted branch ids are never sent; `get-user-branch` filters to the `companyId` sent, or the caller's current company when it is omitted or empty). Branch grants are explicit, so these lists hold only granted branches: with Parent and Level 2 granted but not Level 1, Level 2 nests under Parent (its nearest granted ancestor) and Level 1 is neither shown nor selectable. A branch with no granted ancestor shows as a root. Dropdown trees come from `buildBranchTreeNodes` in ng-shared; the branch list's searchable tree (`buildBranchTree`) lives in `utils/branch-tree.utils.ts`. The backend rejects a parent from another company or one that would create a cycle.
|
|
62
|
+
|
|
61
63
|
## 3. Protect Routes with Guards
|
|
62
64
|
|
|
63
65
|
```typescript
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Component, computed, inject } from "@angular/core";
|
|
3
|
+
import { APP_CONFIG, isCompanyFeatureEnabled } from "@flusys/ng-core";
|
|
4
|
+
import { RouterOutlet } from "@angular/router";
|
|
5
|
+
import { BRANCH_PERMISSIONS, COMPANY_PERMISSIONS, PermissionValidatorService, RouterTabsComponent, SOCIAL_AUTH_CONFIG_PERMISSIONS, TranslatePipe, TranslateService, USER_PERMISSIONS } from "@flusys/ng-shared";
|
|
6
|
+
var AdministrationPageComponent = class AdministrationPageComponent {
|
|
7
|
+
appConfig = inject(APP_CONFIG);
|
|
8
|
+
permissionValidator = inject(PermissionValidatorService);
|
|
9
|
+
translateService = inject(TranslateService);
|
|
10
|
+
allTabs = [
|
|
11
|
+
{
|
|
12
|
+
id: "users",
|
|
13
|
+
labelKey: "administrative.user.title",
|
|
14
|
+
icon: "users",
|
|
15
|
+
route: "users",
|
|
16
|
+
permission: USER_PERMISSIONS.READ
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "companies",
|
|
20
|
+
labelKey: "administrative.company.title",
|
|
21
|
+
icon: "building",
|
|
22
|
+
route: "company",
|
|
23
|
+
permission: COMPANY_PERMISSIONS.READ,
|
|
24
|
+
requiresCompanyFeature: true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "branches",
|
|
28
|
+
labelKey: "administrative.branch.title",
|
|
29
|
+
icon: "sitemap",
|
|
30
|
+
route: "branch",
|
|
31
|
+
permission: BRANCH_PERMISSIONS.READ,
|
|
32
|
+
requiresCompanyFeature: true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "social-config",
|
|
36
|
+
labelKey: "social.config.title",
|
|
37
|
+
icon: "key",
|
|
38
|
+
route: "social-config",
|
|
39
|
+
permission: SOCIAL_AUTH_CONFIG_PERMISSIONS.READ
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig), ...ngDevMode ? [{ debugName: "companyFeatureEnabled" }] : /* istanbul ignore next */ []);
|
|
43
|
+
visibleTabs = computed(() => {
|
|
44
|
+
return this.allTabs.filter((tab) => {
|
|
45
|
+
const hasCompanyFeature = !tab.requiresCompanyFeature || this.companyFeatureEnabled();
|
|
46
|
+
const hasPermission = this.permissionValidator.hasPermission(tab.permission);
|
|
47
|
+
return hasCompanyFeature && hasPermission;
|
|
48
|
+
}).map((tab) => ({
|
|
49
|
+
id: tab.id,
|
|
50
|
+
label: this.translateService.translate(tab.labelKey),
|
|
51
|
+
icon: tab.icon,
|
|
52
|
+
route: tab.route
|
|
53
|
+
}));
|
|
54
|
+
}, ...ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []);
|
|
55
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
56
|
+
minVersion: "12.0.0",
|
|
57
|
+
version: "22.2.1",
|
|
58
|
+
ngImport: i0,
|
|
59
|
+
type: AdministrationPageComponent,
|
|
60
|
+
deps: [],
|
|
61
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
62
|
+
});
|
|
63
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
64
|
+
minVersion: "14.0.0",
|
|
65
|
+
version: "22.2.1",
|
|
66
|
+
type: AdministrationPageComponent,
|
|
67
|
+
isStandalone: true,
|
|
68
|
+
selector: "lib-administration-page",
|
|
69
|
+
ngImport: i0,
|
|
70
|
+
template: `
|
|
71
|
+
<div class="p-4">
|
|
72
|
+
<div class="mb-4">
|
|
73
|
+
<h1 class="text-2xl font-bold m-0">{{ 'administrative.title' | translate }}</h1>
|
|
74
|
+
<p class="text-muted-color mt-1">{{ 'administrative.subtitle' | translate }}</p>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<lib-router-tabs [tabs]="visibleTabs()" class="mb-4" />
|
|
78
|
+
|
|
79
|
+
<div>
|
|
80
|
+
<router-outlet />
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
`,
|
|
84
|
+
isInline: true,
|
|
85
|
+
dependencies: [
|
|
86
|
+
{
|
|
87
|
+
kind: "directive",
|
|
88
|
+
type: RouterOutlet,
|
|
89
|
+
selector: "router-outlet",
|
|
90
|
+
inputs: ["name", "routerOutletData"],
|
|
91
|
+
outputs: [
|
|
92
|
+
"activate",
|
|
93
|
+
"deactivate",
|
|
94
|
+
"attach",
|
|
95
|
+
"detach"
|
|
96
|
+
],
|
|
97
|
+
exportAs: ["outlet"]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
kind: "component",
|
|
101
|
+
type: RouterTabsComponent,
|
|
102
|
+
selector: "lib-router-tabs",
|
|
103
|
+
inputs: ["tabs"]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
kind: "pipe",
|
|
107
|
+
type: TranslatePipe,
|
|
108
|
+
name: "translate"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
114
|
+
minVersion: "12.0.0",
|
|
115
|
+
version: "22.2.1",
|
|
116
|
+
ngImport: i0,
|
|
117
|
+
type: AdministrationPageComponent,
|
|
118
|
+
decorators: [{
|
|
119
|
+
type: Component,
|
|
120
|
+
args: [{
|
|
121
|
+
selector: "lib-administration-page",
|
|
122
|
+
imports: [
|
|
123
|
+
RouterOutlet,
|
|
124
|
+
TranslatePipe,
|
|
125
|
+
RouterTabsComponent
|
|
126
|
+
],
|
|
127
|
+
template: `
|
|
128
|
+
<div class="p-4">
|
|
129
|
+
<div class="mb-4">
|
|
130
|
+
<h1 class="text-2xl font-bold m-0">{{ 'administrative.title' | translate }}</h1>
|
|
131
|
+
<p class="text-muted-color mt-1">{{ 'administrative.subtitle' | translate }}</p>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<lib-router-tabs [tabs]="visibleTabs()" class="mb-4" />
|
|
135
|
+
|
|
136
|
+
<div>
|
|
137
|
+
<router-outlet />
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
`
|
|
141
|
+
}]
|
|
142
|
+
}]
|
|
143
|
+
});
|
|
144
|
+
export { AdministrationPageComponent };
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=flusys-ng-auth-administration-page.component-DmN4KqiR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-administration-page.component-DmN4KqiR.mjs","names":[],"sources":["../../../projects/ng-auth/pages/administration/administration-page.component.ts"],"sourcesContent":["import { Component, computed, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';\nimport {\n BRANCH_PERMISSIONS,\n COMPANY_PERMISSIONS,\n PermissionValidatorService,\n RouterTabItem,\n RouterTabsComponent,\n SOCIAL_AUTH_CONFIG_PERMISSIONS,\n TranslatePipe,\n TranslateService,\n USER_PERMISSIONS,\n} from '@flusys/ng-shared';\n\ninterface ITab {\n id: string;\n labelKey: string;\n icon: string;\n route: string;\n permission: string;\n requiresCompanyFeature?: boolean;\n}\n\n/**\n * Administration Page Component\n * Unified administration page with tabs for:\n * - Users (always visible) - includes permission management via dialogs\n * - Companies (only if company feature enabled)\n * - Branches (only if company feature enabled)\n * - Social Config (social sign-in provider credentials)\n */\n@Component({\n selector: 'lib-administration-page',\n imports: [RouterOutlet, TranslatePipe, RouterTabsComponent],\n template: `\n <div class=\"p-4\">\n <div class=\"mb-4\">\n <h1 class=\"text-2xl font-bold m-0\">{{ 'administrative.title' | translate }}</h1>\n <p class=\"text-muted-color mt-1\">{{ 'administrative.subtitle' | translate }}</p>\n </div>\n\n <lib-router-tabs [tabs]=\"visibleTabs()\" class=\"mb-4\" />\n\n <div>\n <router-outlet />\n </div>\n </div>\n `,\n})\nexport class AdministrationPageComponent {\n private readonly appConfig = inject(APP_CONFIG);\n private readonly permissionValidator = inject(PermissionValidatorService);\n private readonly translateService = inject(TranslateService);\n\n /** All available tabs */\n private readonly allTabs: ITab[] = [\n {\n id: 'users',\n labelKey: 'administrative.user.title',\n icon: 'users',\n route: 'users',\n permission: USER_PERMISSIONS.READ,\n },\n {\n id: 'companies',\n labelKey: 'administrative.company.title',\n icon: 'building',\n route: 'company',\n permission: COMPANY_PERMISSIONS.READ,\n requiresCompanyFeature: true,\n },\n {\n id: 'branches',\n labelKey: 'administrative.branch.title',\n icon: 'sitemap',\n route: 'branch',\n permission: BRANCH_PERMISSIONS.READ,\n requiresCompanyFeature: true,\n },\n {\n id: 'social-config',\n labelKey: 'social.config.title',\n icon: 'key',\n route: 'social-config',\n permission: SOCIAL_AUTH_CONFIG_PERMISSIONS.READ,\n },\n ];\n\n /** Check if company feature is enabled */\n readonly companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig));\n\n /** Visible tabs based on config and permissions */\n readonly visibleTabs = computed<RouterTabItem[]>(() => {\n return this.allTabs\n .filter((tab) => {\n const hasCompanyFeature = !tab.requiresCompanyFeature || this.companyFeatureEnabled();\n const hasPermission = this.permissionValidator.hasPermission(tab.permission);\n return hasCompanyFeature && hasPermission;\n })\n .map((tab) => ({\n id: tab.id,\n label: this.translateService.translate(tab.labelKey),\n icon: tab.icon,\n route: tab.route,\n }));\n });\n}\n"],"mappings":";;;;;AAkDA,IAAa,8BAAb,MAAa,4BAA2B;CACrB,YAAY,OAAO,UAAU;CAC7B,sBAAsB,OAAO,0BAA0B;CACvD,mBAAmB,OAAO,gBAAgB;CAG1C,UAAkB;EACjC;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,iBAAiB;EAC9B;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,oBAAoB;GAChC,wBAAwB;EACzB;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,mBAAmB;GAC/B,wBAAwB;EACzB;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,+BAA+B;EAC5C;CACF;CAGQ,wBAAwB,eAAe,wBAAwB,KAAK,SAAS,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,wBAAA,CAAA,+BAAA,CAAA,CAAA;CAG/E,cAAc,eAA+B;EACpD,OAAO,KAAK,QACT,QAAQ,QAAO;GACd,MAAM,oBAAoB,CAAC,IAAI,0BAA0B,KAAK,sBAAqB;GACnF,MAAM,gBAAgB,KAAK,oBAAoB,cAAc,IAAI,UAAU;GAC3E,OAAO,qBAAqB;EAC9B,CAAC,CAAC,CACD,KAAK,SAAS;GACb,IAAI,IAAI;GACR,OAAO,KAAK,iBAAiB,UAAU,IAAI,QAAQ;GACnD,MAAM,IAAI;GACV,OAAO,IAAI;EACZ,EAAC;CACN,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAxDS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAA2B,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAA3B,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAA2B,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAf5B;;;;;;;;;;;;;;EAaT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAdS;IAAY,UAAA;IAAA,QAAA,CAAA,QAAA,kBAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,UAAA,CAAA,QAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAiB;IAAmB,UAAA;IAAA,QAAA,CAAA,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAlC;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AAgB1B,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAA2B,YAAA,CAAA;EAlBvC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IAAC;IAAc;IAAe;GAAmB;GAC1D,UAAU;;;;;;;;;;;;;;EAcX,CAAA"}
|