oip-common 0.1.2 → 0.1.3
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/fesm2022/oip-common.mjs +58 -30
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +5 -2
- package/package.json +1 -1
package/fesm2022/oip-common.mjs
CHANGED
|
@@ -29,7 +29,7 @@ import { PrimeNG } from 'primeng/config';
|
|
|
29
29
|
import * as i3 from 'primeng/selectbutton';
|
|
30
30
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
31
31
|
import { OidcSecurityService, PublicEventsService, EventTypes, StsConfigHttpLoader } from 'angular-auth-oidc-client';
|
|
32
|
-
import { filter, map, switchMap, catchError } from 'rxjs/operators';
|
|
32
|
+
import { filter, map, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators';
|
|
33
33
|
import { Tabs, TabList, Tab } from 'primeng/tabs';
|
|
34
34
|
import * as i2$2 from 'primeng/avatar';
|
|
35
35
|
import { AvatarModule } from 'primeng/avatar';
|
|
@@ -1475,6 +1475,10 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1475
1475
|
* Stores the decoded access token payload.
|
|
1476
1476
|
*/
|
|
1477
1477
|
this.payload = new BehaviorSubject(null);
|
|
1478
|
+
/**
|
|
1479
|
+
* Stores user-specific data from the login response.
|
|
1480
|
+
*/
|
|
1481
|
+
this.currentUser = new BehaviorSubject(null);
|
|
1478
1482
|
this.publicEventsService
|
|
1479
1483
|
.registerForEvents()
|
|
1480
1484
|
.pipe(filter((event) => event.type === EventTypes.NewAuthenticationResult))
|
|
@@ -1483,14 +1487,17 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1483
1487
|
});
|
|
1484
1488
|
}
|
|
1485
1489
|
getCurrentUser() {
|
|
1486
|
-
return this.
|
|
1490
|
+
return this.currentUser.getValue();
|
|
1491
|
+
}
|
|
1492
|
+
getCurrentUser$() {
|
|
1493
|
+
return this.currentUser.asObservable();
|
|
1487
1494
|
}
|
|
1488
1495
|
/**
|
|
1489
1496
|
* Returns the ID token for the sign-in.
|
|
1490
1497
|
* @returns A string with the id token.
|
|
1491
1498
|
*/
|
|
1492
1499
|
getAccessToken() {
|
|
1493
|
-
return
|
|
1500
|
+
return super.getAccessToken();
|
|
1494
1501
|
}
|
|
1495
1502
|
/**
|
|
1496
1503
|
* Indicates whether the current user has the 'admin' role.
|
|
@@ -1507,7 +1514,7 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1507
1514
|
auth() {
|
|
1508
1515
|
super.checkAuth().subscribe((_response) => {
|
|
1509
1516
|
this.loginResponse.next(_response);
|
|
1510
|
-
this.
|
|
1517
|
+
this.currentUser.next(_response.userData);
|
|
1511
1518
|
this.getPayloadFromAccessToken().subscribe((_token) => {
|
|
1512
1519
|
this.payload.next(_token);
|
|
1513
1520
|
});
|
|
@@ -1528,6 +1535,7 @@ class KeycloakSecurityService extends OidcSecurityService {
|
|
|
1528
1535
|
ngOnDestroy() {
|
|
1529
1536
|
this.loginResponse.complete();
|
|
1530
1537
|
this.payload.complete();
|
|
1538
|
+
this.currentUser.complete();
|
|
1531
1539
|
}
|
|
1532
1540
|
/**
|
|
1533
1541
|
* Checks whether the current access token is expired based on the 'exp' claim.
|
|
@@ -1554,6 +1562,7 @@ class UserService {
|
|
|
1554
1562
|
constructor() {
|
|
1555
1563
|
this.securityService = inject(SecurityService);
|
|
1556
1564
|
this.baseDataService = inject(BaseDataService);
|
|
1565
|
+
this.requestedPhotoEmail = null;
|
|
1557
1566
|
/**
|
|
1558
1567
|
* Stores the user's photo as a data URL or binary blob, depending on how it's processed.
|
|
1559
1568
|
*/
|
|
@@ -1562,7 +1571,12 @@ class UserService {
|
|
|
1562
1571
|
* Indicates whether the user photo has finished loading.
|
|
1563
1572
|
*/
|
|
1564
1573
|
this.photoLoaded = false;
|
|
1565
|
-
this.
|
|
1574
|
+
this.securityService
|
|
1575
|
+
.getCurrentUser$()
|
|
1576
|
+
.pipe(map((user) => user?.email ?? null), filter((email) => !!email), distinctUntilChanged())
|
|
1577
|
+
.subscribe(() => {
|
|
1578
|
+
this.getUserPhoto();
|
|
1579
|
+
});
|
|
1566
1580
|
}
|
|
1567
1581
|
/**
|
|
1568
1582
|
* Returns a short label composed of the user's initials.
|
|
@@ -1585,9 +1599,12 @@ class UserService {
|
|
|
1585
1599
|
getUserPhoto() {
|
|
1586
1600
|
const email = this.securityService.getCurrentUser()?.email;
|
|
1587
1601
|
if (!email) {
|
|
1588
|
-
this.photoLoaded = true;
|
|
1589
1602
|
return;
|
|
1590
1603
|
}
|
|
1604
|
+
if (this.requestedPhotoEmail === email && (this.photoLoaded || this.photo)) {
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
this.requestedPhotoEmail = email;
|
|
1591
1608
|
const url = this.baseDataService.buildUrl(`api/user-profile/get-user-photo?email=${email}`);
|
|
1592
1609
|
this.baseDataService.getBlob(url).then((data) => {
|
|
1593
1610
|
this.createImageFromBlob(data);
|
|
@@ -1988,15 +2005,18 @@ class HttpClient {
|
|
|
1988
2005
|
this.layoutService = inject(LayoutService);
|
|
1989
2006
|
this.baseUrl = "";
|
|
1990
2007
|
this.securityData = null;
|
|
1991
|
-
this.securityWorker = (securityData) =>
|
|
1992
|
-
headers
|
|
2008
|
+
this.securityWorker = (securityData) => {
|
|
2009
|
+
const headers = {
|
|
1993
2010
|
"Accept-language": this.layoutService.language()
|
|
1994
2011
|
? this.layoutService.language()
|
|
1995
2012
|
: "en",
|
|
1996
2013
|
"X-Timezone": this.layoutService.timeZone(),
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2014
|
+
};
|
|
2015
|
+
if (securityData) {
|
|
2016
|
+
headers.Authorization = `Bearer ${securityData}`;
|
|
2017
|
+
}
|
|
2018
|
+
return { headers };
|
|
2019
|
+
};
|
|
2000
2020
|
this.abortControllers = new Map();
|
|
2001
2021
|
this.customFetch = (...fetchParams) => fetch(...fetchParams);
|
|
2002
2022
|
this.baseApiParams = {
|
|
@@ -3128,7 +3148,8 @@ class MenuComponent {
|
|
|
3128
3148
|
];
|
|
3129
3149
|
}
|
|
3130
3150
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3131
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: `
|
|
3151
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: `
|
|
3152
|
+
<div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
|
|
3132
3153
|
<ul class="layout-menu">
|
|
3133
3154
|
@for (item of menuService.menu; track item; let i = $index) {
|
|
3134
3155
|
<ng-container>
|
|
@@ -3148,10 +3169,10 @@ class MenuComponent {
|
|
|
3148
3169
|
}
|
|
3149
3170
|
</ul>
|
|
3150
3171
|
</div>
|
|
3151
|
-
<p-contextMenu [target]="empty"
|
|
3152
|
-
@if (securityService.isAdmin) {
|
|
3153
|
-
<menu-item-create-dialog
|
|
3154
|
-
<menu-item-edit-dialog
|
|
3172
|
+
<p-contextMenu [target]="empty"/>
|
|
3173
|
+
@if (securityService.isAdmin()) {
|
|
3174
|
+
<menu-item-create-dialog/>
|
|
3175
|
+
<menu-item-edit-dialog/>
|
|
3155
3176
|
}`, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i1$4.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "component", type: MenuItemCreateDialogComponent, selector: "menu-item-create-dialog", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MenuItemEditDialogComponent, selector: "menu-item-edit-dialog", inputs: ["visible"], outputs: ["visibleChange"] }] }); }
|
|
3156
3177
|
}
|
|
3157
3178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, decorators: [{
|
|
@@ -3170,7 +3191,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3170
3191
|
providers: [MenuApi],
|
|
3171
3192
|
selector: 'app-menu',
|
|
3172
3193
|
standalone: true,
|
|
3173
|
-
template: `
|
|
3194
|
+
template: `
|
|
3195
|
+
<div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
|
|
3174
3196
|
<ul class="layout-menu">
|
|
3175
3197
|
@for (item of menuService.menu; track item; let i = $index) {
|
|
3176
3198
|
<ng-container>
|
|
@@ -3190,10 +3212,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3190
3212
|
}
|
|
3191
3213
|
</ul>
|
|
3192
3214
|
</div>
|
|
3193
|
-
<p-contextMenu [target]="empty"
|
|
3194
|
-
@if (securityService.isAdmin) {
|
|
3195
|
-
<menu-item-create-dialog
|
|
3196
|
-
<menu-item-edit-dialog
|
|
3215
|
+
<p-contextMenu [target]="empty"/>
|
|
3216
|
+
@if (securityService.isAdmin()) {
|
|
3217
|
+
<menu-item-create-dialog/>
|
|
3218
|
+
<menu-item-edit-dialog/>
|
|
3197
3219
|
}`
|
|
3198
3220
|
}]
|
|
3199
3221
|
}], propDecorators: { menuItemCreateDialogComponent: [{
|
|
@@ -5925,17 +5947,10 @@ class NotificationService {
|
|
|
5925
5947
|
this.securityService = inject(SecurityService);
|
|
5926
5948
|
this.msgService = inject(MsgService);
|
|
5927
5949
|
this.frontendConfig = inject(OIP_FRONTEND_CONFIG);
|
|
5928
|
-
this.
|
|
5929
|
-
this.securityData = token;
|
|
5930
|
-
if (token) {
|
|
5931
|
-
this.connection.stop().then(() => {
|
|
5932
|
-
this.connection.start().then();
|
|
5933
|
-
});
|
|
5934
|
-
}
|
|
5935
|
-
});
|
|
5950
|
+
this.securityData = null;
|
|
5936
5951
|
this.connection = new signalR.HubConnectionBuilder()
|
|
5937
5952
|
.withUrl(this.resolveHubUrl(), {
|
|
5938
|
-
accessTokenFactory: () => this.securityData,
|
|
5953
|
+
accessTokenFactory: () => this.securityData ?? '',
|
|
5939
5954
|
skipNegotiation: true,
|
|
5940
5955
|
transport: signalR.HttpTransportType.WebSockets
|
|
5941
5956
|
})
|
|
@@ -5950,6 +5965,19 @@ class NotificationService {
|
|
|
5950
5965
|
};
|
|
5951
5966
|
this.msgService.add(opt);
|
|
5952
5967
|
});
|
|
5968
|
+
this.securityService.getAccessToken().subscribe((token) => {
|
|
5969
|
+
this.securityData = token;
|
|
5970
|
+
if (!token) {
|
|
5971
|
+
return;
|
|
5972
|
+
}
|
|
5973
|
+
if (this.connection.state === signalR.HubConnectionState.Disconnected) {
|
|
5974
|
+
this.connection.start().catch((error) => console.error('Failed to start notification connection', error));
|
|
5975
|
+
return;
|
|
5976
|
+
}
|
|
5977
|
+
this.connection.stop().then(() => {
|
|
5978
|
+
this.connection.start().catch((error) => console.error('Failed to restart notification connection', error));
|
|
5979
|
+
});
|
|
5980
|
+
});
|
|
5953
5981
|
}
|
|
5954
5982
|
resolveHubUrl() {
|
|
5955
5983
|
if (this.frontendConfig.notificationHubUrl) {
|