varminer-app-header 2.2.3 → 2.2.4
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/AppHeader.d.ts.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +132 -10
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +132 -9
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/localStorage.d.ts +6 -1
- package/dist/utils/localStorage.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -421,13 +421,129 @@ function getAccessTokenFromAuth(auth) {
|
|
|
421
421
|
auth.token;
|
|
422
422
|
return typeof token === "string" && token.length > 0 ? token : undefined;
|
|
423
423
|
}
|
|
424
|
-
|
|
424
|
+
/** True if string looks like a JWT (three base64 parts) or a bearer token, not JSON. */
|
|
425
|
+
function looksLikeToken(s) {
|
|
426
|
+
return s.length > 0 && !s.trimStart().startsWith("{") && !s.trimStart().startsWith("[");
|
|
427
|
+
}
|
|
428
|
+
/** Recursively find first string value at keys accessToken, access_token, or token. */
|
|
429
|
+
function findTokenInObject(obj) {
|
|
430
|
+
if (obj === null || obj === undefined)
|
|
431
|
+
return undefined;
|
|
432
|
+
if (typeof obj === "string")
|
|
433
|
+
return looksLikeToken(obj) ? obj : undefined;
|
|
434
|
+
if (typeof obj !== "object")
|
|
435
|
+
return undefined;
|
|
436
|
+
const rec = obj;
|
|
437
|
+
const direct = rec.accessToken ?? rec.access_token ?? rec.token;
|
|
438
|
+
if (typeof direct === "string" && looksLikeToken(direct))
|
|
439
|
+
return direct;
|
|
440
|
+
for (const key of Object.keys(rec)) {
|
|
441
|
+
const found = findTokenInObject(rec[key]);
|
|
442
|
+
if (found)
|
|
443
|
+
return found;
|
|
444
|
+
}
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
447
|
+
/** Parse redux-persist style value (may be double stringified). */
|
|
448
|
+
function parsePersistValue(raw) {
|
|
449
|
+
if (!raw)
|
|
450
|
+
return null;
|
|
451
|
+
try {
|
|
452
|
+
const first = JSON.parse(raw);
|
|
453
|
+
if (typeof first === "string") {
|
|
454
|
+
try {
|
|
455
|
+
return JSON.parse(first);
|
|
456
|
+
}
|
|
457
|
+
catch {
|
|
458
|
+
return first;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return first;
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/** Get a nested value that may be a string (need parse) or already an object. */
|
|
468
|
+
function parseNestedValue(val) {
|
|
469
|
+
if (val == null)
|
|
470
|
+
return null;
|
|
471
|
+
if (typeof val === "string")
|
|
472
|
+
return parsePersistValue(val);
|
|
473
|
+
return val;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Extract access token from persist:userdb shape: authDetails (string) → parse → auth.accessToken.
|
|
477
|
+
* Structure: { authDetails: "{\"auth\":{\"accessToken\":\"...\"}}", profileInformation: "...", _persist: "..." }
|
|
478
|
+
*/
|
|
479
|
+
function getTokenFromUserDbPersist(parsed) {
|
|
480
|
+
const authDetails = parsed.authDetails;
|
|
481
|
+
const inner = parseNestedValue(authDetails);
|
|
482
|
+
const obj = typeof inner === "object" && inner !== null ? inner : null;
|
|
483
|
+
if (!obj)
|
|
484
|
+
return undefined;
|
|
485
|
+
const auth = obj.auth;
|
|
486
|
+
const authObj = typeof auth === "object" && auth !== null ? auth : null;
|
|
487
|
+
if (!authObj)
|
|
488
|
+
return undefined;
|
|
489
|
+
const token = authObj.accessToken ??
|
|
490
|
+
authObj.access_token ??
|
|
491
|
+
authObj.token;
|
|
492
|
+
return typeof token === "string" && looksLikeToken(token) ? token : undefined;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Get access token from all known storage keys (header, IAM, userdb, and plain keys).
|
|
496
|
+
* persist:userdb shape: authDetails (stringified) contains auth.accessToken.
|
|
497
|
+
*/
|
|
498
|
+
function getAccessTokenForRequest() {
|
|
499
|
+
const keysToTry = [
|
|
500
|
+
PERSIST_HEADER_KEY,
|
|
501
|
+
"persist:linn-i-am",
|
|
502
|
+
"persist:userdb",
|
|
503
|
+
"token",
|
|
504
|
+
"accessToken",
|
|
505
|
+
"auth",
|
|
506
|
+
];
|
|
507
|
+
for (const key of keysToTry) {
|
|
508
|
+
const raw = localStorage.getItem(key);
|
|
509
|
+
if (!raw)
|
|
510
|
+
continue;
|
|
511
|
+
const parsed = key.startsWith("persist:") ? parsePersistValue(raw) : (() => { try {
|
|
512
|
+
return JSON.parse(raw);
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
return raw;
|
|
516
|
+
} })();
|
|
517
|
+
const token = findTokenInObject(parsed);
|
|
518
|
+
if (token)
|
|
519
|
+
return token;
|
|
520
|
+
if (key.startsWith("persist:")) {
|
|
521
|
+
const outer = typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
522
|
+
if (outer) {
|
|
523
|
+
if (key === "persist:userdb") {
|
|
524
|
+
const fromUserDb = getTokenFromUserDbPersist(outer);
|
|
525
|
+
if (fromUserDb)
|
|
526
|
+
return fromUserDb;
|
|
527
|
+
}
|
|
528
|
+
for (const k of Object.keys(outer)) {
|
|
529
|
+
const inner = parseNestedValue(outer[k]);
|
|
530
|
+
const t = findTokenInObject(inner);
|
|
531
|
+
if (t)
|
|
532
|
+
return t;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return getAccessTokenFromAuth(getAllDataFromStorage().auth);
|
|
538
|
+
}
|
|
539
|
+
const fetchProfilePictureAsBlobUrl = async (baseUrl = "http://objectstore.impact0mics.local:9012", accessTokenOverride) => {
|
|
425
540
|
try {
|
|
426
541
|
const profilePictureUrl = getProfilePictureUrl(baseUrl);
|
|
427
542
|
if (!profilePictureUrl)
|
|
428
543
|
return null;
|
|
429
|
-
const
|
|
430
|
-
|
|
544
|
+
const accessToken = (typeof accessTokenOverride === "string" && accessTokenOverride.length > 0
|
|
545
|
+
? accessTokenOverride
|
|
546
|
+
: null) ?? getAccessTokenForRequest();
|
|
431
547
|
const headers = {};
|
|
432
548
|
if (accessToken) {
|
|
433
549
|
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
@@ -563,7 +679,7 @@ const DEFAULT_ROUTES = {
|
|
|
563
679
|
profile: "/user/profile",
|
|
564
680
|
logout: "/user/login",
|
|
565
681
|
};
|
|
566
|
-
const AppHeader = ({ language: languageProp }) => {
|
|
682
|
+
const AppHeader = ({ language: languageProp, accessToken: accessTokenProp }) => {
|
|
567
683
|
// Get initial language from props, URL, localStorage, or default to 'en'
|
|
568
684
|
const getInitialLanguage = () => {
|
|
569
685
|
// Priority 1: Props
|
|
@@ -660,12 +776,18 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
660
776
|
userRole = userRole || profileData.role || profileData.userRole || "";
|
|
661
777
|
}
|
|
662
778
|
}
|
|
779
|
+
const avatarSrc = storedUser?.avatar ??
|
|
780
|
+
allData.auth?.avatar ??
|
|
781
|
+
allData.profile?.avatar;
|
|
782
|
+
const initialsVal = storedUser?.initials ??
|
|
783
|
+
allData.auth?.initials ??
|
|
784
|
+
allData.profile?.initials;
|
|
663
785
|
return {
|
|
664
786
|
name: userName || "",
|
|
665
787
|
email: userEmail || "",
|
|
666
788
|
role: userRole || "",
|
|
667
|
-
avatar:
|
|
668
|
-
initials:
|
|
789
|
+
avatar: typeof avatarSrc === "string" ? avatarSrc : undefined,
|
|
790
|
+
initials: typeof initialsVal === "string" ? initialsVal : undefined,
|
|
669
791
|
};
|
|
670
792
|
});
|
|
671
793
|
const [notificationCount, setNotificationCount] = React.useState(() => {
|
|
@@ -680,8 +802,8 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
680
802
|
// Fetch profile picture from API when component mounts or user data changes
|
|
681
803
|
React.useEffect(() => {
|
|
682
804
|
const fetchProfilePicture = async () => {
|
|
683
|
-
|
|
684
|
-
const blobUrl = await fetchProfilePictureAsBlobUrl();
|
|
805
|
+
const token = accessTokenProp ?? getAccessTokenForRequest();
|
|
806
|
+
const blobUrl = await fetchProfilePictureAsBlobUrl(undefined, token ?? undefined);
|
|
685
807
|
if (blobUrl) {
|
|
686
808
|
// Clean up previous blob URL if it exists
|
|
687
809
|
setProfilePictureBlobUrl((prevUrl) => {
|
|
@@ -702,7 +824,7 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
702
824
|
return null;
|
|
703
825
|
});
|
|
704
826
|
};
|
|
705
|
-
}, []); //
|
|
827
|
+
}, [accessTokenProp]); // Refetch when accessToken prop changes (e.g. after login)
|
|
706
828
|
React.useEffect(() => {
|
|
707
829
|
const allData = getAllDataFromStorage();
|
|
708
830
|
let userName = "";
|
|
@@ -1039,6 +1161,7 @@ exports.DrawerProvider = DrawerProvider;
|
|
|
1039
1161
|
exports.PERSIST_HEADER_KEY = PERSIST_HEADER_KEY;
|
|
1040
1162
|
exports.USER_DETAILS_STORAGE_KEY = USER_DETAILS_STORAGE_KEY;
|
|
1041
1163
|
exports.fetchProfilePictureAsBlobUrl = fetchProfilePictureAsBlobUrl;
|
|
1164
|
+
exports.getAccessTokenForRequest = getAccessTokenForRequest;
|
|
1042
1165
|
exports.getAllDataFromStorage = getAllDataFromStorage;
|
|
1043
1166
|
exports.getI18nLocaleFromStorage = getI18nLocaleFromStorage;
|
|
1044
1167
|
exports.getMessageCountFromStorage = getMessageCountFromStorage;
|