@mcurros2/microm 1.1.167-0 → 1.1.170-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +343 -276
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1345,6 +1345,8 @@ parcelRegister("dU7Zq", function(module, exports) {
|
|
|
1345
1345
|
|
|
1346
1346
|
$parcel$export(module.exports, "MicroMClient", function () { return $16abd72d1aa9b62d$export$6118e57c65bf19ee; });
|
|
1347
1347
|
|
|
1348
|
+
var $lTNXP = parcelRequire("lTNXP");
|
|
1349
|
+
|
|
1348
1350
|
var $cfO6r = parcelRequire("cfO6r");
|
|
1349
1351
|
|
|
1350
1352
|
var $hDJ3w = parcelRequire("hDJ3w");
|
|
@@ -1397,6 +1399,7 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1397
1399
|
getAPPID() {
|
|
1398
1400
|
return this.#APP_ID;
|
|
1399
1401
|
}
|
|
1402
|
+
//*** Record access
|
|
1400
1403
|
startRecordPaths() {
|
|
1401
1404
|
this.#RECORD_PATHS = true;
|
|
1402
1405
|
}
|
|
@@ -1441,6 +1444,9 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1441
1444
|
};
|
|
1442
1445
|
}
|
|
1443
1446
|
}
|
|
1447
|
+
async #saveRecordedAccessData(data) {
|
|
1448
|
+
await this.#DATA_STORAGE.saveData(this.#APP_ID, (0, $brSbF.RECORDED_ACCESS_DATA_STORAGE_KEY), data);
|
|
1449
|
+
}
|
|
1444
1450
|
async #saveAllRecordedAccess() {
|
|
1445
1451
|
if (this.#RECORD_PATHS) {
|
|
1446
1452
|
const result = (0, $brSbF.generateCSharpGetRoutePaths)(this.#RECORDED_PATHS);
|
|
@@ -1448,39 +1454,73 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1448
1454
|
console.log(result);
|
|
1449
1455
|
}
|
|
1450
1456
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
await this.#
|
|
1457
|
+
//*** OIDC flows
|
|
1458
|
+
async oidcLoginAndRedirect(options) {
|
|
1459
|
+
const authorizeUrl = await this.#startOidcLogin(options);
|
|
1460
|
+
window.location.href = authorizeUrl;
|
|
1454
1461
|
}
|
|
1455
|
-
async
|
|
1456
|
-
const
|
|
1462
|
+
async #startOidcLogin(options) {
|
|
1463
|
+
const { targetLinkUri: targetLinkUri, extraParams: extraParams } = options;
|
|
1464
|
+
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'OIDC PAR request timed out');
|
|
1457
1465
|
try {
|
|
1458
|
-
await this.#
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
const
|
|
1466
|
+
const localDeviceId = await this.#getLocalDeviceId();
|
|
1467
|
+
// Prepare OIDC client PAR request parameters
|
|
1468
|
+
// required OIDC parameters are server-managed
|
|
1469
|
+
const params = new URLSearchParams();
|
|
1470
|
+
if (targetLinkUri) params.set('target_link_uri', targetLinkUri);
|
|
1471
|
+
params.set('local_device_id', localDeviceId);
|
|
1472
|
+
params.set('client_id', this.#APP_ID);
|
|
1473
|
+
if (extraParams) {
|
|
1474
|
+
for (const [k, v] of Object.entries(extraParams))if (v != null) {
|
|
1475
|
+
// Avoid overriding security-related parameters that are server-managed.
|
|
1476
|
+
if ((0, $lTNXP.isIn)(k, 'response_type', 'scope', 'state', 'nonce', 'code_challenge', 'code_challenge_method', 'client_id', 'request_uri', 'redirect_uri')) {
|
|
1477
|
+
console.warn(`Ignoring OIDC extraParam '${k}' because it is server-managed.`);
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
params.set(k, v);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
const parUrl = `${this.#API_URL}/${this.#APP_ID}/oidc-client/par`;
|
|
1484
|
+
const response = await fetch(parUrl, {
|
|
1462
1485
|
method: 'POST',
|
|
1463
1486
|
headers: {
|
|
1464
|
-
"Content-Type": "application/
|
|
1465
|
-
"Authorization": `Bearer ${this.#TOKEN?.access_token || ''}`
|
|
1487
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1466
1488
|
},
|
|
1467
1489
|
mode: this.#REQUEST_MODE,
|
|
1468
1490
|
cache: 'no-store',
|
|
1469
1491
|
credentials: 'include',
|
|
1470
1492
|
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1471
1493
|
signal: loginTimeout.signal,
|
|
1472
|
-
body:
|
|
1494
|
+
body: params.toString()
|
|
1473
1495
|
});
|
|
1474
|
-
if (!response.ok)
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1496
|
+
if (!response.ok) {
|
|
1497
|
+
const text = await response.text().catch(()=>'');
|
|
1498
|
+
throw {
|
|
1499
|
+
status: response.status,
|
|
1500
|
+
statusMessage: response.statusText,
|
|
1501
|
+
message: text || response.statusText,
|
|
1502
|
+
url: response.url
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
const data = await response.json();
|
|
1506
|
+
if (!data.authorize_url) throw {
|
|
1507
|
+
status: 500,
|
|
1508
|
+
statusMessage: 'invalid_par_response',
|
|
1509
|
+
message: data.error_description || data.error || 'PAR response missing authorize_url',
|
|
1510
|
+
url: parUrl
|
|
1479
1511
|
};
|
|
1512
|
+
return data.authorize_url;
|
|
1480
1513
|
} finally{
|
|
1481
1514
|
loginTimeout.clear();
|
|
1482
1515
|
}
|
|
1483
1516
|
}
|
|
1517
|
+
//*** Local login/logout
|
|
1518
|
+
get LOGGED_IN_USER() {
|
|
1519
|
+
return this.#TOKEN?.claims;
|
|
1520
|
+
}
|
|
1521
|
+
async getRememberUser() {
|
|
1522
|
+
return await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$REMEMBER_USER_DATA_KEY);
|
|
1523
|
+
}
|
|
1484
1524
|
async isLoggedIn() {
|
|
1485
1525
|
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'Login request timed out');
|
|
1486
1526
|
try {
|
|
@@ -1515,27 +1555,6 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1515
1555
|
}
|
|
1516
1556
|
return !!this.#TOKEN?.access_token && new Date() < new Date(this.#TOKEN.expiration);
|
|
1517
1557
|
}
|
|
1518
|
-
get LOGGED_IN_USER() {
|
|
1519
|
-
return this.#TOKEN?.claims;
|
|
1520
|
-
}
|
|
1521
|
-
async updateClientClaims(claims) {
|
|
1522
|
-
if (this.#TOKEN) {
|
|
1523
|
-
this.#TOKEN.claims = claims;
|
|
1524
|
-
await this.#setToken(this.#TOKEN);
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
async #getLocalDeviceId() {
|
|
1528
|
-
const local_device = await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$LOCAL_DEVICE_ID_KEY);
|
|
1529
|
-
if (local_device !== null) {
|
|
1530
|
-
this.#LOCAL_DEVICE_ID = local_device;
|
|
1531
|
-
return local_device;
|
|
1532
|
-
}
|
|
1533
|
-
// Generate a new local device ID if it doesn't exist
|
|
1534
|
-
const randomId = "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c)=>(+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16));
|
|
1535
|
-
await this.#DATA_STORAGE.saveData(this.#APP_ID, $16abd72d1aa9b62d$var$LOCAL_DEVICE_ID_KEY, randomId);
|
|
1536
|
-
this.#LOCAL_DEVICE_ID = randomId;
|
|
1537
|
-
return randomId;
|
|
1538
|
-
}
|
|
1539
1558
|
async login(username, password, rememberme) {
|
|
1540
1559
|
//Intentionally not accounting for tokenRefreshInProgress (see refresh logic)
|
|
1541
1560
|
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'Login request timed out');
|
|
@@ -1598,6 +1617,45 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1598
1617
|
loginTimeout.clear();
|
|
1599
1618
|
}
|
|
1600
1619
|
}
|
|
1620
|
+
async localLogoff() {
|
|
1621
|
+
await this.#removeToken();
|
|
1622
|
+
await this.#deleteEnabledMenus();
|
|
1623
|
+
}
|
|
1624
|
+
async logoff() {
|
|
1625
|
+
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'Login request timed out');
|
|
1626
|
+
try {
|
|
1627
|
+
await this.#removeToken();
|
|
1628
|
+
await this.#deleteEnabledMenus();
|
|
1629
|
+
if (this.#RECORD_PATHS) await this.#saveAllRecordedAccess();
|
|
1630
|
+
const response = await fetch(`${this.#API_URL}/${this.#APP_ID}/auth/logoff`, {
|
|
1631
|
+
method: 'POST',
|
|
1632
|
+
headers: {
|
|
1633
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
1634
|
+
"Authorization": `Bearer ${this.#TOKEN?.access_token || ''}`
|
|
1635
|
+
},
|
|
1636
|
+
mode: this.#REQUEST_MODE,
|
|
1637
|
+
cache: 'no-store',
|
|
1638
|
+
credentials: 'include',
|
|
1639
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1640
|
+
signal: loginTimeout.signal,
|
|
1641
|
+
body: JSON.stringify({})
|
|
1642
|
+
});
|
|
1643
|
+
if (!response.ok) throw {
|
|
1644
|
+
status: response.status,
|
|
1645
|
+
statusMessage: response.statusText,
|
|
1646
|
+
message: response.statusText,
|
|
1647
|
+
url: response.url
|
|
1648
|
+
};
|
|
1649
|
+
} finally{
|
|
1650
|
+
loginTimeout.clear();
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
async updateClientClaims(claims) {
|
|
1654
|
+
if (this.#TOKEN) {
|
|
1655
|
+
this.#TOKEN.claims = claims;
|
|
1656
|
+
await this.#setToken(this.#TOKEN);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1601
1659
|
async recoveryemail(username) {
|
|
1602
1660
|
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT * 4, 'Login request timed out');
|
|
1603
1661
|
try {
|
|
@@ -1660,6 +1718,99 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1660
1718
|
loginTimeout.clear();
|
|
1661
1719
|
}
|
|
1662
1720
|
}
|
|
1721
|
+
async #getLocalDeviceId() {
|
|
1722
|
+
const local_device = await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$LOCAL_DEVICE_ID_KEY);
|
|
1723
|
+
if (local_device !== null) {
|
|
1724
|
+
this.#LOCAL_DEVICE_ID = local_device;
|
|
1725
|
+
return local_device;
|
|
1726
|
+
}
|
|
1727
|
+
// Generate a new local device ID if it doesn't exist
|
|
1728
|
+
const randomId = "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c)=>(+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16));
|
|
1729
|
+
await this.#DATA_STORAGE.saveData(this.#APP_ID, $16abd72d1aa9b62d$var$LOCAL_DEVICE_ID_KEY, randomId);
|
|
1730
|
+
this.#LOCAL_DEVICE_ID = randomId;
|
|
1731
|
+
return randomId;
|
|
1732
|
+
}
|
|
1733
|
+
async #loadToken() {
|
|
1734
|
+
if (!this.#TOKEN) this.#TOKEN = await this.#TOKEN_STORAGE.readToken(this.#APP_ID);
|
|
1735
|
+
}
|
|
1736
|
+
async #setToken(token) {
|
|
1737
|
+
await this.#TOKEN_STORAGE.saveToken(this.#APP_ID, token);
|
|
1738
|
+
this.#TOKEN = token;
|
|
1739
|
+
}
|
|
1740
|
+
async #removeToken() {
|
|
1741
|
+
await this.#TOKEN_STORAGE.deleteToken(this.#APP_ID);
|
|
1742
|
+
this.#TOKEN = null;
|
|
1743
|
+
}
|
|
1744
|
+
async #checkAndRefreshToken() {
|
|
1745
|
+
await this.#loadToken();
|
|
1746
|
+
await this.#readTimeZoneOffset();
|
|
1747
|
+
if (!this.#TOKEN) return;
|
|
1748
|
+
const renewalAheadPeriod = 60000;
|
|
1749
|
+
const now = new Date();
|
|
1750
|
+
const expiration = new Date(this.#TOKEN.expiration);
|
|
1751
|
+
if (now > new Date(expiration.getTime() - renewalAheadPeriod)) await this.#refreshToken();
|
|
1752
|
+
}
|
|
1753
|
+
async #refreshToken() {
|
|
1754
|
+
// Check if a token refresh is already in progress.
|
|
1755
|
+
// If so, return that promise instead of starting a new request.
|
|
1756
|
+
if (this.#tokenRefreshInProgress) {
|
|
1757
|
+
console.warn('Token refresh already in progress');
|
|
1758
|
+
return this.#tokenRefreshInProgress;
|
|
1759
|
+
}
|
|
1760
|
+
const _performTokenRefresh = async ()=>{
|
|
1761
|
+
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'Login request timed out');
|
|
1762
|
+
try {
|
|
1763
|
+
if (!this.#TOKEN) throw new Error('Token not found');
|
|
1764
|
+
//console.log('Refreshing token');
|
|
1765
|
+
const old_token = this.#TOKEN;
|
|
1766
|
+
const response = await fetch(`${this.#API_URL}/${this.#APP_ID}/auth/refresh`, {
|
|
1767
|
+
method: 'POST',
|
|
1768
|
+
headers: {
|
|
1769
|
+
"Content-Type": "application/json; charset=utf-8"
|
|
1770
|
+
},
|
|
1771
|
+
mode: this.#REQUEST_MODE,
|
|
1772
|
+
cache: 'no-store',
|
|
1773
|
+
credentials: 'include',
|
|
1774
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1775
|
+
signal: loginTimeout.signal,
|
|
1776
|
+
body: JSON.stringify({
|
|
1777
|
+
Bearer: this.#TOKEN.access_token,
|
|
1778
|
+
RefreshToken: this.#TOKEN.refresh_token
|
|
1779
|
+
})
|
|
1780
|
+
});
|
|
1781
|
+
if (!response.ok) throw {
|
|
1782
|
+
status: response?.status,
|
|
1783
|
+
statusMessage: response?.statusText,
|
|
1784
|
+
message: response?.statusText,
|
|
1785
|
+
url: response?.url
|
|
1786
|
+
};
|
|
1787
|
+
const data = await response.json();
|
|
1788
|
+
if (data && data.access_token) {
|
|
1789
|
+
const new_token = new (0, $78KzE.MicroMToken)(data.access_token, data.expires_in, data['refresh-token'], data.token_type, this.#TOKEN.claims);
|
|
1790
|
+
if (old_token !== this.#TOKEN) throw new Error("Current token was changed while refreshing.");
|
|
1791
|
+
await this.#setToken(new_token);
|
|
1792
|
+
//console.log('Token refreshed', new_token);
|
|
1793
|
+
return;
|
|
1794
|
+
} else //console.log('Unexpected result', data);
|
|
1795
|
+
throw {
|
|
1796
|
+
statusMessage: 'Unexpected result',
|
|
1797
|
+
url: response.url
|
|
1798
|
+
};
|
|
1799
|
+
} catch (error) {
|
|
1800
|
+
//console.log('RefreshToken', error);
|
|
1801
|
+
throw error;
|
|
1802
|
+
} finally{
|
|
1803
|
+
this.#tokenRefreshInProgress = null; // Clear the ongoing refresh promise once done.
|
|
1804
|
+
loginTimeout.clear();
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
this.#tokenRefreshInProgress = _performTokenRefresh();
|
|
1808
|
+
return this.#tokenRefreshInProgress;
|
|
1809
|
+
}
|
|
1810
|
+
//*** Timezone offset
|
|
1811
|
+
get TIMEZONE_OFFSET() {
|
|
1812
|
+
return this.#TIMEZONE_OFFSET;
|
|
1813
|
+
}
|
|
1663
1814
|
async #saveTimeZoneOffset(data) {
|
|
1664
1815
|
await this.#DATA_STORAGE.saveData(this.#APP_ID, $16abd72d1aa9b62d$var$TIMEZONE_OFFSET_DATA_KEY, data);
|
|
1665
1816
|
}
|
|
@@ -1684,8 +1835,13 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1684
1835
|
await this.#saveTimeZoneOffset(offset);
|
|
1685
1836
|
return result;
|
|
1686
1837
|
}
|
|
1687
|
-
|
|
1688
|
-
|
|
1838
|
+
//*** Enabled menus
|
|
1839
|
+
async getMenus() {
|
|
1840
|
+
if (this.#ENABLED_MENUS.size === 0) {
|
|
1841
|
+
const data = await this.#readEnabledMenus();
|
|
1842
|
+
this.#ENABLED_MENUS = data ? new Set(data) : new Set();
|
|
1843
|
+
}
|
|
1844
|
+
return this.#ENABLED_MENUS;
|
|
1689
1845
|
}
|
|
1690
1846
|
async #getAPIEnabledMenus(username, abort_signal = null) {
|
|
1691
1847
|
if (!this.#TOKEN) return;
|
|
@@ -1702,12 +1858,45 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1702
1858
|
await this.#saveEnabledMenus(menu_items);
|
|
1703
1859
|
this.#ENABLED_MENUS = new Set(menu_items);
|
|
1704
1860
|
}
|
|
1705
|
-
async
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1861
|
+
async #saveEnabledMenus(data) {
|
|
1862
|
+
await this.#DATA_STORAGE.saveData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY, data);
|
|
1863
|
+
}
|
|
1864
|
+
async #readEnabledMenus() {
|
|
1865
|
+
return await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY);
|
|
1866
|
+
}
|
|
1867
|
+
async #deleteEnabledMenus() {
|
|
1868
|
+
await this.#DATA_STORAGE.deleteData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY);
|
|
1869
|
+
}
|
|
1870
|
+
//*** File upload/download
|
|
1871
|
+
getDocumentURL(fileGuid) {
|
|
1872
|
+
return fileGuid ? `${this.#API_URL}/${this.#APP_ID}/serve/${fileGuid}` : '';
|
|
1873
|
+
}
|
|
1874
|
+
getThumbnailURL(fileGuid, max_size = 150, quality = 75) {
|
|
1875
|
+
return fileGuid ? `${this.#API_URL}/${this.#APP_ID}/thumbnail/${fileGuid}/${max_size}/${quality}` : '';
|
|
1876
|
+
}
|
|
1877
|
+
async upload(file, fileprocess_id, abort_signal = null, max_size = 150, quality = 75, onProgress = ()=>{}) {
|
|
1878
|
+
return this.#uploadFile(file, fileprocess_id, abort_signal, max_size, quality, onProgress);
|
|
1879
|
+
}
|
|
1880
|
+
async downloadBlob(fileUrl, abort_signal = null) {
|
|
1881
|
+
await this.#checkAndRefreshToken();
|
|
1882
|
+
if (!this.#TOKEN) throw {
|
|
1883
|
+
status: 401,
|
|
1884
|
+
statusMessage: `Can't execute request: Not logged in`
|
|
1885
|
+
};
|
|
1886
|
+
const response = await fetch(fileUrl, {
|
|
1887
|
+
headers: {
|
|
1888
|
+
...this.#TOKEN ? {
|
|
1889
|
+
"Authorization": `Bearer ${this.#TOKEN.access_token}`
|
|
1890
|
+
} : {}
|
|
1891
|
+
},
|
|
1892
|
+
mode: this.#REQUEST_MODE,
|
|
1893
|
+
cache: 'no-store',
|
|
1894
|
+
credentials: 'include',
|
|
1895
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1896
|
+
signal: abort_signal
|
|
1897
|
+
});
|
|
1898
|
+
if (!response.ok) throw new Error(`Network error: ${response.status} - ${response.statusText}`);
|
|
1899
|
+
return await response.blob();
|
|
1711
1900
|
}
|
|
1712
1901
|
async #uploadFile(file, fileprocess_id, abort_signal = null, max_size = 150, quality = 75, onProgress = ()=>{}) {
|
|
1713
1902
|
await this.#checkAndRefreshToken();
|
|
@@ -1768,223 +1957,7 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
1768
1957
|
xhr.send(file);
|
|
1769
1958
|
});
|
|
1770
1959
|
}
|
|
1771
|
-
|
|
1772
|
-
// Check if a token refresh is already in progress.
|
|
1773
|
-
// If so, return that promise instead of starting a new request.
|
|
1774
|
-
if (this.#tokenRefreshInProgress) {
|
|
1775
|
-
console.warn('Token refresh already in progress');
|
|
1776
|
-
return this.#tokenRefreshInProgress;
|
|
1777
|
-
}
|
|
1778
|
-
const _performTokenRefresh = async ()=>{
|
|
1779
|
-
const loginTimeout = new (0, $dF8o7.TimeoutSignal)(this.#LOGIN_TIMEOUT, 'Login request timed out');
|
|
1780
|
-
try {
|
|
1781
|
-
if (!this.#TOKEN) throw new Error('Token not found');
|
|
1782
|
-
//console.log('Refreshing token');
|
|
1783
|
-
const old_token = this.#TOKEN;
|
|
1784
|
-
const response = await fetch(`${this.#API_URL}/${this.#APP_ID}/auth/refresh`, {
|
|
1785
|
-
method: 'POST',
|
|
1786
|
-
headers: {
|
|
1787
|
-
"Content-Type": "application/json; charset=utf-8"
|
|
1788
|
-
},
|
|
1789
|
-
mode: this.#REQUEST_MODE,
|
|
1790
|
-
cache: 'no-store',
|
|
1791
|
-
credentials: 'include',
|
|
1792
|
-
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1793
|
-
signal: loginTimeout.signal,
|
|
1794
|
-
body: JSON.stringify({
|
|
1795
|
-
Bearer: this.#TOKEN.access_token,
|
|
1796
|
-
RefreshToken: this.#TOKEN.refresh_token
|
|
1797
|
-
})
|
|
1798
|
-
});
|
|
1799
|
-
if (!response.ok) throw {
|
|
1800
|
-
status: response?.status,
|
|
1801
|
-
statusMessage: response?.statusText,
|
|
1802
|
-
message: response?.statusText,
|
|
1803
|
-
url: response?.url
|
|
1804
|
-
};
|
|
1805
|
-
const data = await response.json();
|
|
1806
|
-
if (data && data.access_token) {
|
|
1807
|
-
const new_token = new (0, $78KzE.MicroMToken)(data.access_token, data.expires_in, data['refresh-token'], data.token_type, this.#TOKEN.claims);
|
|
1808
|
-
if (old_token !== this.#TOKEN) throw new Error("Current token was changed while refreshing.");
|
|
1809
|
-
await this.#setToken(new_token);
|
|
1810
|
-
//console.log('Token refreshed', new_token);
|
|
1811
|
-
return;
|
|
1812
|
-
} else //console.log('Unexpected result', data);
|
|
1813
|
-
throw {
|
|
1814
|
-
statusMessage: 'Unexpected result',
|
|
1815
|
-
url: response.url
|
|
1816
|
-
};
|
|
1817
|
-
} catch (error) {
|
|
1818
|
-
//console.log('RefreshToken', error);
|
|
1819
|
-
throw error;
|
|
1820
|
-
} finally{
|
|
1821
|
-
this.#tokenRefreshInProgress = null; // Clear the ongoing refresh promise once done.
|
|
1822
|
-
loginTimeout.clear();
|
|
1823
|
-
}
|
|
1824
|
-
};
|
|
1825
|
-
this.#tokenRefreshInProgress = _performTokenRefresh();
|
|
1826
|
-
return this.#tokenRefreshInProgress;
|
|
1827
|
-
}
|
|
1828
|
-
async getRememberUser() {
|
|
1829
|
-
return await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$REMEMBER_USER_DATA_KEY);
|
|
1830
|
-
}
|
|
1831
|
-
async #saveRecordedAccessData(data) {
|
|
1832
|
-
await this.#DATA_STORAGE.saveData(this.#APP_ID, (0, $brSbF.RECORDED_ACCESS_DATA_STORAGE_KEY), data);
|
|
1833
|
-
}
|
|
1834
|
-
async #saveEnabledMenus(data) {
|
|
1835
|
-
await this.#DATA_STORAGE.saveData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY, data);
|
|
1836
|
-
}
|
|
1837
|
-
async #readEnabledMenus() {
|
|
1838
|
-
return await this.#DATA_STORAGE.readData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY);
|
|
1839
|
-
}
|
|
1840
|
-
async #deleteEnabledMenus() {
|
|
1841
|
-
await this.#DATA_STORAGE.deleteData(this.#APP_ID, $16abd72d1aa9b62d$var$ENABLED_MENUS_DATA_KEY);
|
|
1842
|
-
}
|
|
1843
|
-
async #loadToken() {
|
|
1844
|
-
if (!this.#TOKEN) this.#TOKEN = await this.#TOKEN_STORAGE.readToken(this.#APP_ID);
|
|
1845
|
-
}
|
|
1846
|
-
async #setToken(token) {
|
|
1847
|
-
await this.#TOKEN_STORAGE.saveToken(this.#APP_ID, token);
|
|
1848
|
-
this.#TOKEN = token;
|
|
1849
|
-
}
|
|
1850
|
-
async #removeToken() {
|
|
1851
|
-
await this.#TOKEN_STORAGE.deleteToken(this.#APP_ID);
|
|
1852
|
-
this.#TOKEN = null;
|
|
1853
|
-
}
|
|
1854
|
-
async #checkAndRefreshToken() {
|
|
1855
|
-
await this.#loadToken();
|
|
1856
|
-
await this.#readTimeZoneOffset();
|
|
1857
|
-
if (!this.#TOKEN) return;
|
|
1858
|
-
const renewalAheadPeriod = 60000;
|
|
1859
|
-
const now = new Date();
|
|
1860
|
-
const expiration = new Date(this.#TOKEN.expiration);
|
|
1861
|
-
if (now > new Date(expiration.getTime() - renewalAheadPeriod)) await this.#refreshToken();
|
|
1862
|
-
}
|
|
1863
|
-
async #submitToAPI(entity_name, parent_keys, values, recordsSelection, action, abort_signal = null, additional_route = null) {
|
|
1864
|
-
const extra_route = additional_route !== null ? `/${additional_route}` : '';
|
|
1865
|
-
const route = `${this.#API_URL}/${this.#APP_ID}/ent/${entity_name}/${action}${extra_route}`;
|
|
1866
|
-
try {
|
|
1867
|
-
await this.#checkAndRefreshToken();
|
|
1868
|
-
if (!this.#TOKEN) throw {
|
|
1869
|
-
status: 401,
|
|
1870
|
-
statusMessage: `Can't execute request: Not logged in`,
|
|
1871
|
-
url: route
|
|
1872
|
-
};
|
|
1873
|
-
const body = JSON.stringify({
|
|
1874
|
-
ParentKeys: parent_keys,
|
|
1875
|
-
Values: values,
|
|
1876
|
-
RecordsSelection: recordsSelection
|
|
1877
|
-
}, (0, $hDJ3w.JSONDateWithTimezoneReplacer));
|
|
1878
|
-
const res = await fetch(route, {
|
|
1879
|
-
method: 'POST',
|
|
1880
|
-
headers: {
|
|
1881
|
-
"Content-Type": "application/json; charset=utf-8",
|
|
1882
|
-
"Authorization": `Bearer ${this.#TOKEN.access_token}`
|
|
1883
|
-
},
|
|
1884
|
-
mode: this.#REQUEST_MODE,
|
|
1885
|
-
cache: 'no-store',
|
|
1886
|
-
credentials: 'include',
|
|
1887
|
-
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1888
|
-
signal: abort_signal,
|
|
1889
|
-
body: body
|
|
1890
|
-
});
|
|
1891
|
-
if (!res.ok) throw {
|
|
1892
|
-
status: res?.status,
|
|
1893
|
-
statusMessage: res?.statusText,
|
|
1894
|
-
message: res?.statusText,
|
|
1895
|
-
url: res?.url
|
|
1896
|
-
};
|
|
1897
|
-
const data = await res.json();
|
|
1898
|
-
return data;
|
|
1899
|
-
} catch (error) {
|
|
1900
|
-
abort_signal = null;
|
|
1901
|
-
if (this.#REDIRECT_ON_401) {
|
|
1902
|
-
if (error.status === 401) {
|
|
1903
|
-
console.warn(`${route} 401, redirecting to login page: ${this.#REDIRECT_ON_401}`);
|
|
1904
|
-
await this.localLogoff();
|
|
1905
|
-
window.location.href = this.#REDIRECT_ON_401;
|
|
1906
|
-
}
|
|
1907
|
-
} else throw error;
|
|
1908
|
-
throw error;
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
async #submitToPublicAPI(entity_name, parent_keys, values, recordsSelection, action, abort_signal = null, additional_route = null) {
|
|
1912
|
-
const extra_route = additional_route !== null ? `/${additional_route}` : '';
|
|
1913
|
-
const route = `${this.#API_URL}/${this.#APP_ID}/public/${entity_name}/${action}${extra_route}`;
|
|
1914
|
-
const body = JSON.stringify({
|
|
1915
|
-
ParentKeys: parent_keys,
|
|
1916
|
-
Values: values,
|
|
1917
|
-
RecordsSelection: recordsSelection
|
|
1918
|
-
}, (0, $hDJ3w.JSONDateWithTimezoneReplacer));
|
|
1919
|
-
const res = await fetch(route, {
|
|
1920
|
-
method: 'POST',
|
|
1921
|
-
headers: {
|
|
1922
|
-
"Content-Type": "application/json; charset=utf-8"
|
|
1923
|
-
},
|
|
1924
|
-
mode: this.#REQUEST_MODE,
|
|
1925
|
-
cache: 'no-store',
|
|
1926
|
-
credentials: 'include',
|
|
1927
|
-
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1928
|
-
signal: abort_signal,
|
|
1929
|
-
body: body
|
|
1930
|
-
});
|
|
1931
|
-
if (!res.ok) throw {
|
|
1932
|
-
status: res?.status,
|
|
1933
|
-
statusMessage: res?.statusText,
|
|
1934
|
-
message: res?.statusText,
|
|
1935
|
-
url: res?.url
|
|
1936
|
-
};
|
|
1937
|
-
const data = await res.json();
|
|
1938
|
-
abort_signal = null;
|
|
1939
|
-
return data;
|
|
1940
|
-
}
|
|
1941
|
-
async downloadBlob(fileUrl, abort_signal = null) {
|
|
1942
|
-
await this.#checkAndRefreshToken();
|
|
1943
|
-
if (!this.#TOKEN) throw {
|
|
1944
|
-
status: 401,
|
|
1945
|
-
statusMessage: `Can't execute request: Not logged in`
|
|
1946
|
-
};
|
|
1947
|
-
const response = await fetch(fileUrl, {
|
|
1948
|
-
headers: {
|
|
1949
|
-
...this.#TOKEN ? {
|
|
1950
|
-
"Authorization": `Bearer ${this.#TOKEN.access_token}`
|
|
1951
|
-
} : {}
|
|
1952
|
-
},
|
|
1953
|
-
mode: this.#REQUEST_MODE,
|
|
1954
|
-
cache: 'no-store',
|
|
1955
|
-
credentials: 'include',
|
|
1956
|
-
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
1957
|
-
signal: abort_signal
|
|
1958
|
-
});
|
|
1959
|
-
if (!response.ok) throw new Error(`Network error: ${response.status} - ${response.statusText}`);
|
|
1960
|
-
return await response.blob();
|
|
1961
|
-
}
|
|
1962
|
-
#isPublicAPI(entity_name, action, proc_name, action_name) {
|
|
1963
|
-
const endpoint = this.#publicEndpoints[entity_name];
|
|
1964
|
-
if (endpoint) switch(action){
|
|
1965
|
-
case "get":
|
|
1966
|
-
return (endpoint.AllowedAccess & 8) !== 0;
|
|
1967
|
-
case "insert":
|
|
1968
|
-
return (endpoint.AllowedAccess & 1) !== 0;
|
|
1969
|
-
case "update":
|
|
1970
|
-
return (endpoint.AllowedAccess & 2) !== 0;
|
|
1971
|
-
case "delete":
|
|
1972
|
-
return (endpoint.AllowedAccess & 4) !== 0;
|
|
1973
|
-
case "lookup":
|
|
1974
|
-
return (endpoint.AllowedAccess & 16) !== 0;
|
|
1975
|
-
case "action":
|
|
1976
|
-
return endpoint.AllowedActions && action_name && endpoint.AllowedActions.has(action_name) || false;
|
|
1977
|
-
case "view":
|
|
1978
|
-
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
1979
|
-
case "proc":
|
|
1980
|
-
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
1981
|
-
case "process":
|
|
1982
|
-
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
1983
|
-
default:
|
|
1984
|
-
return false;
|
|
1985
|
-
}
|
|
1986
|
-
return false;
|
|
1987
|
-
}
|
|
1960
|
+
//*** Entities API
|
|
1988
1961
|
async get(entity_name, parent_keys, values, abort_signal = null) {
|
|
1989
1962
|
this.#recordAccess({
|
|
1990
1963
|
entityName: entity_name,
|
|
@@ -2090,14 +2063,108 @@ class $16abd72d1aa9b62d$export$6118e57c65bf19ee {
|
|
|
2090
2063
|
});
|
|
2091
2064
|
return this.#submitToAPI(entity_name, parent_keys, values, [], "import", abort_signal, import_procname);
|
|
2092
2065
|
}
|
|
2093
|
-
async
|
|
2094
|
-
|
|
2066
|
+
async #submitToAPI(entity_name, parent_keys, values, recordsSelection, action, abort_signal = null, additional_route = null) {
|
|
2067
|
+
const extra_route = additional_route !== null ? `/${additional_route}` : '';
|
|
2068
|
+
const route = `${this.#API_URL}/${this.#APP_ID}/ent/${entity_name}/${action}${extra_route}`;
|
|
2069
|
+
try {
|
|
2070
|
+
await this.#checkAndRefreshToken();
|
|
2071
|
+
if (!this.#TOKEN) throw {
|
|
2072
|
+
status: 401,
|
|
2073
|
+
statusMessage: `Can't execute request: Not logged in`,
|
|
2074
|
+
url: route
|
|
2075
|
+
};
|
|
2076
|
+
const body = JSON.stringify({
|
|
2077
|
+
ParentKeys: parent_keys,
|
|
2078
|
+
Values: values,
|
|
2079
|
+
RecordsSelection: recordsSelection
|
|
2080
|
+
}, (0, $hDJ3w.JSONDateWithTimezoneReplacer));
|
|
2081
|
+
const res = await fetch(route, {
|
|
2082
|
+
method: 'POST',
|
|
2083
|
+
headers: {
|
|
2084
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
2085
|
+
"Authorization": `Bearer ${this.#TOKEN.access_token}`
|
|
2086
|
+
},
|
|
2087
|
+
mode: this.#REQUEST_MODE,
|
|
2088
|
+
cache: 'no-store',
|
|
2089
|
+
credentials: 'include',
|
|
2090
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
2091
|
+
signal: abort_signal,
|
|
2092
|
+
body: body
|
|
2093
|
+
});
|
|
2094
|
+
if (!res.ok) throw {
|
|
2095
|
+
status: res?.status,
|
|
2096
|
+
statusMessage: res?.statusText,
|
|
2097
|
+
message: res?.statusText,
|
|
2098
|
+
url: res?.url
|
|
2099
|
+
};
|
|
2100
|
+
const data = await res.json();
|
|
2101
|
+
return data;
|
|
2102
|
+
} catch (error) {
|
|
2103
|
+
if (this.#REDIRECT_ON_401 && error.status === 401) {
|
|
2104
|
+
console.warn(`${route} 401, redirecting to login page: ${this.#REDIRECT_ON_401}`);
|
|
2105
|
+
await this.localLogoff();
|
|
2106
|
+
window.location.href = this.#REDIRECT_ON_401;
|
|
2107
|
+
// return intentionally omitted
|
|
2108
|
+
}
|
|
2109
|
+
// MMC: this line should never execute if the redirect happens.
|
|
2110
|
+
// In case the browser, webview or environment for any reason fails to redirect, we still throw the error to the caller.
|
|
2111
|
+
throw error;
|
|
2112
|
+
}
|
|
2095
2113
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2114
|
+
async #submitToPublicAPI(entity_name, parent_keys, values, recordsSelection, action, abort_signal = null, additional_route = null) {
|
|
2115
|
+
const extra_route = additional_route !== null ? `/${additional_route}` : '';
|
|
2116
|
+
const route = `${this.#API_URL}/${this.#APP_ID}/public/${entity_name}/${action}${extra_route}`;
|
|
2117
|
+
const body = JSON.stringify({
|
|
2118
|
+
ParentKeys: parent_keys,
|
|
2119
|
+
Values: values,
|
|
2120
|
+
RecordsSelection: recordsSelection
|
|
2121
|
+
}, (0, $hDJ3w.JSONDateWithTimezoneReplacer));
|
|
2122
|
+
const res = await fetch(route, {
|
|
2123
|
+
method: 'POST',
|
|
2124
|
+
headers: {
|
|
2125
|
+
"Content-Type": "application/json; charset=utf-8"
|
|
2126
|
+
},
|
|
2127
|
+
mode: this.#REQUEST_MODE,
|
|
2128
|
+
cache: 'no-store',
|
|
2129
|
+
credentials: 'include',
|
|
2130
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
2131
|
+
signal: abort_signal,
|
|
2132
|
+
body: body
|
|
2133
|
+
});
|
|
2134
|
+
if (!res.ok) throw {
|
|
2135
|
+
status: res?.status,
|
|
2136
|
+
statusMessage: res?.statusText,
|
|
2137
|
+
message: res?.statusText,
|
|
2138
|
+
url: res?.url
|
|
2139
|
+
};
|
|
2140
|
+
const data = await res.json();
|
|
2141
|
+
return data;
|
|
2098
2142
|
}
|
|
2099
|
-
|
|
2100
|
-
|
|
2143
|
+
#isPublicAPI(entity_name, action, proc_name, action_name) {
|
|
2144
|
+
const endpoint = this.#publicEndpoints[entity_name];
|
|
2145
|
+
if (endpoint) switch(action){
|
|
2146
|
+
case "get":
|
|
2147
|
+
return (endpoint.AllowedAccess & 8) !== 0;
|
|
2148
|
+
case "insert":
|
|
2149
|
+
return (endpoint.AllowedAccess & 1) !== 0;
|
|
2150
|
+
case "update":
|
|
2151
|
+
return (endpoint.AllowedAccess & 2) !== 0;
|
|
2152
|
+
case "delete":
|
|
2153
|
+
return (endpoint.AllowedAccess & 4) !== 0;
|
|
2154
|
+
case "lookup":
|
|
2155
|
+
return (endpoint.AllowedAccess & 16) !== 0;
|
|
2156
|
+
case "action":
|
|
2157
|
+
return endpoint.AllowedActions && action_name && endpoint.AllowedActions.has(action_name) || false;
|
|
2158
|
+
case "view":
|
|
2159
|
+
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
2160
|
+
case "proc":
|
|
2161
|
+
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
2162
|
+
case "process":
|
|
2163
|
+
return endpoint.AllowedProcs && proc_name && endpoint.AllowedProcs.has(proc_name) || false;
|
|
2164
|
+
default:
|
|
2165
|
+
return false;
|
|
2166
|
+
}
|
|
2167
|
+
return false;
|
|
2101
2168
|
}
|
|
2102
2169
|
}
|
|
2103
2170
|
|
|
@@ -3245,7 +3312,7 @@ var $hv0CN = parcelRequire("hv0CN");
|
|
|
3245
3312
|
|
|
3246
3313
|
var $hxOxo = parcelRequire("hxOxo");
|
|
3247
3314
|
|
|
3248
|
-
var $
|
|
3315
|
+
var $01mqs = parcelRequire("01mqs");
|
|
3249
3316
|
|
|
3250
3317
|
var $lULWw = parcelRequire("lULWw");
|
|
3251
3318
|
|
|
@@ -3368,7 +3435,7 @@ $parcel$exportWildcard(module.exports, $bJhnF);
|
|
|
3368
3435
|
$parcel$exportWildcard(module.exports, $RUzV3);
|
|
3369
3436
|
$parcel$exportWildcard(module.exports, $hv0CN);
|
|
3370
3437
|
$parcel$exportWildcard(module.exports, $hxOxo);
|
|
3371
|
-
$parcel$exportWildcard(module.exports, $
|
|
3438
|
+
$parcel$exportWildcard(module.exports, $01mqs);
|
|
3372
3439
|
$parcel$exportWildcard(module.exports, $lULWw);
|
|
3373
3440
|
$parcel$exportWildcard(module.exports, $3HRFn);
|
|
3374
3441
|
$parcel$exportWildcard(module.exports, $3Zdna);
|
|
@@ -4600,17 +4667,17 @@ function $9dfe1d3e4dcf7b26$export$65ed9482db2257fa(props) {
|
|
|
4600
4667
|
|
|
4601
4668
|
});
|
|
4602
4669
|
|
|
4603
|
-
parcelRegister("
|
|
4670
|
+
parcelRegister("01mqs", function(module, exports) {
|
|
4604
4671
|
|
|
4605
|
-
$parcel$export(module.exports, "useExecuteServerAction", function () { return $
|
|
4672
|
+
$parcel$export(module.exports, "useExecuteServerAction", function () { return $b401857d6bbb5b85$export$5e89f28b2f6c2d01; });
|
|
4606
4673
|
|
|
4607
4674
|
parcelRequire("2eyXi");
|
|
4608
4675
|
var $iKzSR = parcelRequire("iKzSR");
|
|
4609
4676
|
parcelRequire("6Rdyz");
|
|
4610
4677
|
var $98ddT = parcelRequire("98ddT");
|
|
4611
|
-
function $
|
|
4678
|
+
function $b401857d6bbb5b85$export$5e89f28b2f6c2d01(entity, actionName) {
|
|
4612
4679
|
const [status, setStatus] = (0, $b4te3$react.useState)({
|
|
4613
|
-
loading:
|
|
4680
|
+
loading: false
|
|
4614
4681
|
});
|
|
4615
4682
|
const cancellation = (0, $b4te3$react.useRef)(new AbortController());
|
|
4616
4683
|
const done = (0, $b4te3$react.useRef)(false);
|
|
@@ -35804,7 +35871,7 @@ function $404ec2751816fed2$export$a6c7ac8248d6e38a(props) {
|
|
|
35804
35871
|
return /*#__PURE__*/ (0, $b4te3$reactjsxruntime.jsx)((0, $b4te3$mantinecore.Anchor), {
|
|
35805
35872
|
href: to,
|
|
35806
35873
|
onClick: (e)=>{
|
|
35807
|
-
e.preventDefault;
|
|
35874
|
+
e.preventDefault();
|
|
35808
35875
|
navigate(to);
|
|
35809
35876
|
},
|
|
35810
35877
|
children: children
|