varminer-app-header 2.2.3 → 2.2.5
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 +163 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +163 -10
- 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/AppHeader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../src/AppHeader.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAe,MAAM,SAAS,CAAC;AAKtD,OAAO,sBAAsB,CAAC;AAQ9B,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../src/AppHeader.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAe,MAAM,SAAS,CAAC;AAKtD,OAAO,sBAAsB,CAAC;AAQ9B,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAwzBvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ interface UserProfile {
|
|
|
11
11
|
}
|
|
12
12
|
interface AppHeaderProps {
|
|
13
13
|
language?: 'en' | 'es';
|
|
14
|
+
/** When provided, used as Bearer token for profile picture and other authenticated requests. */
|
|
15
|
+
accessToken?: string | null;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
declare const AppHeader: React__default.FC<AppHeaderProps>;
|
|
@@ -119,7 +121,12 @@ declare const getAllDataFromStorage: () => any;
|
|
|
119
121
|
* @returns Profile picture URL or null if user_id is not available
|
|
120
122
|
*/
|
|
121
123
|
declare const getProfilePictureUrl: (baseUrl?: string) => string | null;
|
|
122
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Get access token from all known storage keys (header, IAM, userdb, and plain keys).
|
|
126
|
+
* persist:userdb shape: authDetails (stringified) contains auth.accessToken.
|
|
127
|
+
*/
|
|
128
|
+
declare function getAccessTokenForRequest(): string | undefined;
|
|
129
|
+
declare const fetchProfilePictureAsBlobUrl: (baseUrl?: string, accessTokenOverride?: string | null) => Promise<string | null>;
|
|
123
130
|
|
|
124
|
-
export { AppHeader, DrawerProvider, PERSIST_HEADER_KEY, USER_DETAILS_STORAGE_KEY, fetchProfilePictureAsBlobUrl, getAllDataFromStorage, getI18nLocaleFromStorage, getMessageCountFromStorage, getNotificationCountFromStorage, getProfilePictureUrl, getStoredUserDetails, getTranslations, getUserDataFromStorage, setHeaderAuth, setI18nLocaleToStorage, translations, useDrawer };
|
|
131
|
+
export { AppHeader, DrawerProvider, PERSIST_HEADER_KEY, USER_DETAILS_STORAGE_KEY, fetchProfilePictureAsBlobUrl, getAccessTokenForRequest, getAllDataFromStorage, getI18nLocaleFromStorage, getMessageCountFromStorage, getNotificationCountFromStorage, getProfilePictureUrl, getStoredUserDetails, getTranslations, getUserDataFromStorage, setHeaderAuth, setI18nLocaleToStorage, translations, useDrawer };
|
|
125
132
|
export type { AppHeaderProps, HeaderAuthState, SupportedLanguage, Translations, UserDetailsItem, UserDetailsStoredResponse, UserProfile };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,sBAAsB,EACtB,+BAA+B,EAC/B,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,sBAAsB,EACtB,+BAA+B,EAC/B,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -401,17 +401,161 @@ function getAccessTokenFromAuth(auth) {
|
|
|
401
401
|
auth.token;
|
|
402
402
|
return typeof token === "string" && token.length > 0 ? token : undefined;
|
|
403
403
|
}
|
|
404
|
-
|
|
404
|
+
/** True if string looks like a JWT (three base64 parts) or a bearer token, not JSON. */
|
|
405
|
+
function looksLikeToken(s) {
|
|
406
|
+
return s.length > 0 && !s.trimStart().startsWith("{") && !s.trimStart().startsWith("[");
|
|
407
|
+
}
|
|
408
|
+
/** Recursively find first string value at keys accessToken, access_token, or token. */
|
|
409
|
+
function findTokenInObject(obj) {
|
|
410
|
+
if (obj === null || obj === undefined)
|
|
411
|
+
return undefined;
|
|
412
|
+
if (typeof obj === "string")
|
|
413
|
+
return looksLikeToken(obj) ? obj : undefined;
|
|
414
|
+
if (typeof obj !== "object")
|
|
415
|
+
return undefined;
|
|
416
|
+
const rec = obj;
|
|
417
|
+
const direct = rec.accessToken ?? rec.access_token ?? rec.token;
|
|
418
|
+
if (typeof direct === "string" && looksLikeToken(direct))
|
|
419
|
+
return direct;
|
|
420
|
+
for (const key of Object.keys(rec)) {
|
|
421
|
+
const found = findTokenInObject(rec[key]);
|
|
422
|
+
if (found)
|
|
423
|
+
return found;
|
|
424
|
+
}
|
|
425
|
+
return undefined;
|
|
426
|
+
}
|
|
427
|
+
/** Parse redux-persist style value (may be double stringified). */
|
|
428
|
+
function parsePersistValue(raw) {
|
|
429
|
+
if (!raw)
|
|
430
|
+
return null;
|
|
405
431
|
try {
|
|
432
|
+
const first = JSON.parse(raw);
|
|
433
|
+
if (typeof first === "string") {
|
|
434
|
+
try {
|
|
435
|
+
return JSON.parse(first);
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
return first;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return first;
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/** Get a nested value that may be a string (need parse) or already an object. */
|
|
448
|
+
function parseNestedValue(val) {
|
|
449
|
+
if (val == null)
|
|
450
|
+
return null;
|
|
451
|
+
if (typeof val === "string")
|
|
452
|
+
return parsePersistValue(val);
|
|
453
|
+
return val;
|
|
454
|
+
}
|
|
455
|
+
const AUTH_DEBUG = true; // set to false to disable access-token debug logs
|
|
456
|
+
/**
|
|
457
|
+
* Extract access token from persist:userdb shape: authDetails (string) → parse → auth.accessToken.
|
|
458
|
+
* Structure: { authDetails: "{\"auth\":{\"accessToken\":\"...\"}}", profileInformation: "...", _persist: "..." }
|
|
459
|
+
*/
|
|
460
|
+
function getTokenFromUserDbPersist(parsed) {
|
|
461
|
+
console.log("[header-auth] getTokenFromUserDbPersist: parsed keys", Object.keys(parsed));
|
|
462
|
+
const authDetails = parsed.authDetails;
|
|
463
|
+
const inner = parseNestedValue(authDetails);
|
|
464
|
+
const obj = typeof inner === "object" && inner !== null ? inner : null;
|
|
465
|
+
console.log("[header-auth] getTokenFromUserDbPersist: inner type", typeof inner, "obj keys", obj ? Object.keys(obj) : null);
|
|
466
|
+
if (!obj)
|
|
467
|
+
return undefined;
|
|
468
|
+
const auth = obj.auth;
|
|
469
|
+
const authObj = typeof auth === "object" && auth !== null ? auth : null;
|
|
470
|
+
console.log("[header-auth] getTokenFromUserDbPersist: authObj keys", authObj ? Object.keys(authObj) : null);
|
|
471
|
+
if (!authObj)
|
|
472
|
+
return undefined;
|
|
473
|
+
const token = authObj.accessToken ??
|
|
474
|
+
authObj.access_token ??
|
|
475
|
+
authObj.token;
|
|
476
|
+
const ok = typeof token === "string" && looksLikeToken(token);
|
|
477
|
+
console.log("[header-auth] getTokenFromUserDbPersist: token found", !!ok, "length", typeof token === "string" ? token.length : 0);
|
|
478
|
+
return ok ? token : undefined;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Get access token from all known storage keys (header, IAM, userdb, and plain keys).
|
|
482
|
+
* persist:userdb shape: authDetails (stringified) contains auth.accessToken.
|
|
483
|
+
*/
|
|
484
|
+
function getAccessTokenForRequest() {
|
|
485
|
+
console.log("[header-auth] getAccessTokenForRequest: start");
|
|
486
|
+
const keysToTry = [
|
|
487
|
+
PERSIST_HEADER_KEY,
|
|
488
|
+
"persist:linn-i-am",
|
|
489
|
+
"persist:userdb",
|
|
490
|
+
"token",
|
|
491
|
+
"accessToken",
|
|
492
|
+
"auth",
|
|
493
|
+
];
|
|
494
|
+
for (const key of keysToTry) {
|
|
495
|
+
const raw = localStorage.getItem(key);
|
|
496
|
+
console.log("[header-auth] getAccessTokenForRequest: key", key, "raw present", !!raw, "raw length", raw?.length ?? 0);
|
|
497
|
+
if (!raw)
|
|
498
|
+
continue;
|
|
499
|
+
const parsed = key.startsWith("persist:") ? parsePersistValue(raw) : (() => { try {
|
|
500
|
+
return JSON.parse(raw);
|
|
501
|
+
}
|
|
502
|
+
catch {
|
|
503
|
+
return raw;
|
|
504
|
+
} })();
|
|
505
|
+
const token = findTokenInObject(parsed);
|
|
506
|
+
if (token) {
|
|
507
|
+
console.log("[header-auth] getAccessTokenForRequest: token from findTokenInObject(parsed), key", key);
|
|
508
|
+
return token;
|
|
509
|
+
}
|
|
510
|
+
if (key.startsWith("persist:")) {
|
|
511
|
+
const outer = typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
512
|
+
if (outer) {
|
|
513
|
+
if (key === "persist:userdb") {
|
|
514
|
+
const fromUserDb = getTokenFromUserDbPersist(outer);
|
|
515
|
+
if (fromUserDb) {
|
|
516
|
+
console.log("[header-auth] getAccessTokenForRequest: token from getTokenFromUserDbPersist");
|
|
517
|
+
return fromUserDb;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
for (const k of Object.keys(outer)) {
|
|
521
|
+
const inner = parseNestedValue(outer[k]);
|
|
522
|
+
const t = findTokenInObject(inner);
|
|
523
|
+
if (t) {
|
|
524
|
+
console.log("[header-auth] getAccessTokenForRequest: token from inner key", k);
|
|
525
|
+
return t;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const allData = getAllDataFromStorage();
|
|
532
|
+
const fallback = getAccessTokenFromAuth(allData.auth);
|
|
533
|
+
console.log("[header-auth] getAccessTokenForRequest: fallback getAllDataFromStorage().auth, token present", !!fallback);
|
|
534
|
+
return fallback;
|
|
535
|
+
}
|
|
536
|
+
const fetchProfilePictureAsBlobUrl = async (baseUrl = "http://objectstore.impact0mics.local:9012", accessTokenOverride) => {
|
|
537
|
+
try {
|
|
538
|
+
if (AUTH_DEBUG)
|
|
539
|
+
console.log("[header-auth] fetchProfilePictureAsBlobUrl: start, accessTokenOverride present", typeof accessTokenOverride === "string" && accessTokenOverride.length > 0);
|
|
406
540
|
const profilePictureUrl = getProfilePictureUrl(baseUrl);
|
|
407
|
-
if (!profilePictureUrl)
|
|
541
|
+
if (!profilePictureUrl) {
|
|
542
|
+
if (AUTH_DEBUG)
|
|
543
|
+
console.log("[header-auth] fetchProfilePictureAsBlobUrl: no profilePictureUrl, abort");
|
|
408
544
|
return null;
|
|
409
|
-
|
|
410
|
-
|
|
545
|
+
}
|
|
546
|
+
if (AUTH_DEBUG)
|
|
547
|
+
console.log("[header-auth] fetchProfilePictureAsBlobUrl: profilePictureUrl", profilePictureUrl);
|
|
548
|
+
const accessToken = (typeof accessTokenOverride === "string" && accessTokenOverride.length > 0
|
|
549
|
+
? accessTokenOverride
|
|
550
|
+
: null) ?? getAccessTokenForRequest();
|
|
551
|
+
if (AUTH_DEBUG)
|
|
552
|
+
console.log("[header-auth] fetchProfilePictureAsBlobUrl: accessToken present", !!accessToken, "length", accessToken?.length ?? 0);
|
|
411
553
|
const headers = {};
|
|
412
554
|
if (accessToken) {
|
|
413
555
|
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
414
556
|
}
|
|
557
|
+
if (AUTH_DEBUG)
|
|
558
|
+
console.log("[header-auth] fetchProfilePictureAsBlobUrl: request headers", { ...headers, Authorization: headers["Authorization"] ? "Bearer ***" : "(none)" });
|
|
415
559
|
const response = await fetch(profilePictureUrl, { method: "GET", headers });
|
|
416
560
|
if (!response.ok) {
|
|
417
561
|
console.warn(`Failed to fetch profile picture: ${response.status} ${response.statusText}`);
|
|
@@ -543,7 +687,7 @@ const DEFAULT_ROUTES = {
|
|
|
543
687
|
profile: "/user/profile",
|
|
544
688
|
logout: "/user/login",
|
|
545
689
|
};
|
|
546
|
-
const AppHeader = ({ language: languageProp }) => {
|
|
690
|
+
const AppHeader = ({ language: languageProp, accessToken: accessTokenProp }) => {
|
|
547
691
|
// Get initial language from props, URL, localStorage, or default to 'en'
|
|
548
692
|
const getInitialLanguage = () => {
|
|
549
693
|
// Priority 1: Props
|
|
@@ -640,12 +784,18 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
640
784
|
userRole = userRole || profileData.role || profileData.userRole || "";
|
|
641
785
|
}
|
|
642
786
|
}
|
|
787
|
+
const avatarSrc = storedUser?.avatar ??
|
|
788
|
+
allData.auth?.avatar ??
|
|
789
|
+
allData.profile?.avatar;
|
|
790
|
+
const initialsVal = storedUser?.initials ??
|
|
791
|
+
allData.auth?.initials ??
|
|
792
|
+
allData.profile?.initials;
|
|
643
793
|
return {
|
|
644
794
|
name: userName || "",
|
|
645
795
|
email: userEmail || "",
|
|
646
796
|
role: userRole || "",
|
|
647
|
-
avatar:
|
|
648
|
-
initials:
|
|
797
|
+
avatar: typeof avatarSrc === "string" ? avatarSrc : undefined,
|
|
798
|
+
initials: typeof initialsVal === "string" ? initialsVal : undefined,
|
|
649
799
|
};
|
|
650
800
|
});
|
|
651
801
|
const [notificationCount, setNotificationCount] = React__default.useState(() => {
|
|
@@ -660,8 +810,10 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
660
810
|
// Fetch profile picture from API when component mounts or user data changes
|
|
661
811
|
React__default.useEffect(() => {
|
|
662
812
|
const fetchProfilePicture = async () => {
|
|
663
|
-
|
|
664
|
-
const
|
|
813
|
+
console.log("[header-auth] AppHeader: profile picture effect, accessTokenProp present", !!accessTokenProp);
|
|
814
|
+
const token = accessTokenProp ?? getAccessTokenForRequest();
|
|
815
|
+
console.log("[header-auth] AppHeader: token for request present", !!token, "from prop", !!accessTokenProp);
|
|
816
|
+
const blobUrl = await fetchProfilePictureAsBlobUrl(undefined, token ?? undefined);
|
|
665
817
|
if (blobUrl) {
|
|
666
818
|
// Clean up previous blob URL if it exists
|
|
667
819
|
setProfilePictureBlobUrl((prevUrl) => {
|
|
@@ -682,7 +834,7 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
682
834
|
return null;
|
|
683
835
|
});
|
|
684
836
|
};
|
|
685
|
-
}, []); //
|
|
837
|
+
}, [accessTokenProp]); // Refetch when accessToken prop changes (e.g. after login)
|
|
686
838
|
React__default.useEffect(() => {
|
|
687
839
|
const allData = getAllDataFromStorage();
|
|
688
840
|
let userName = "";
|
|
@@ -1014,5 +1166,5 @@ const AppHeader = ({ language: languageProp }) => {
|
|
|
1014
1166
|
}, children: jsx(MoreIcon, {}) }) })] }) }), renderMobileMenu, renderMenu] }));
|
|
1015
1167
|
};
|
|
1016
1168
|
|
|
1017
|
-
export { AppHeader, DrawerProvider, PERSIST_HEADER_KEY, USER_DETAILS_STORAGE_KEY, fetchProfilePictureAsBlobUrl, getAllDataFromStorage, getI18nLocaleFromStorage, getMessageCountFromStorage, getNotificationCountFromStorage, getProfilePictureUrl, getStoredUserDetails, getTranslations, getUserDataFromStorage, setHeaderAuth, setI18nLocaleToStorage, translations, useDrawer };
|
|
1169
|
+
export { AppHeader, DrawerProvider, PERSIST_HEADER_KEY, USER_DETAILS_STORAGE_KEY, fetchProfilePictureAsBlobUrl, getAccessTokenForRequest, getAllDataFromStorage, getI18nLocaleFromStorage, getMessageCountFromStorage, getNotificationCountFromStorage, getProfilePictureUrl, getStoredUserDetails, getTranslations, getUserDataFromStorage, setHeaderAuth, setI18nLocaleToStorage, translations, useDrawer };
|
|
1018
1170
|
//# sourceMappingURL=index.esm.js.map
|