@stokr/components-library 3.0.27 → 3.0.28

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.
@@ -15,6 +15,7 @@ import { SocialLink, ArrowDown } from "../Footer/FooterMenu.styles.js";
15
15
  import { Collapse } from "react-collapse";
16
16
  import { usePrevious, useMobileView } from "../../utils/customHooks.js";
17
17
  import { checkTodoStatus } from "../../utils/check-todo-status.js";
18
+ import { hasLoggedInSession } from "../../utils/user-identity.js";
18
19
  import { Breakdown } from "../breakdown/Breakdown.js";
19
20
  import { socialSvg } from "../Footer/FooterMenu.js";
20
21
  import { Wrapper, FlexContainer } from "../Grid/Grid.styles.js";
@@ -255,7 +256,7 @@ function HeaderView({
255
256
  }
256
257
  ),
257
258
  isMobile && checkTodoStatus(user) > 0 && !signupFlow && /* @__PURE__ */ jsx(NotificationCounter, { mobile: true, isActive: currentActiveMenu === "main", children: checkTodoStatus(user) }),
258
- /* @__PURE__ */ jsx(HeaderQuickNav, { isUserLogged: user?._id || user?.uid, children: /* @__PURE__ */ jsx(Fragment, { children: user?._id || user?.uid ? /* @__PURE__ */ jsx(Fragment, { children: signupFlow ? /* @__PURE__ */ jsx(Button, { onClick: logoutUser, children: "Log Out" }) : /* @__PURE__ */ jsxs(FlexContainer, { itemsCenter: true, children: [
259
+ /* @__PURE__ */ jsx(HeaderQuickNav, { isUserLogged: hasLoggedInSession(user), children: /* @__PURE__ */ jsx(Fragment, { children: hasLoggedInSession(user) ? /* @__PURE__ */ jsx(Fragment, { children: signupFlow ? /* @__PURE__ */ jsx(Button, { onClick: logoutUser, children: "Log Out" }) : /* @__PURE__ */ jsxs(FlexContainer, { itemsCenter: true, children: [
259
260
  /* @__PURE__ */ jsx(Breakdown, { children: /* @__PURE__ */ jsx(
260
261
  LoginButton,
261
262
  {
@@ -324,7 +325,7 @@ function HeaderView({
324
325
  ),
325
326
  /* @__PURE__ */ jsx(MobileMenuItem, { children: /* @__PURE__ */ jsx(MobileMenuLink, { href: newPlatformUrl + "/team", children: "Team" }) })
326
327
  ] }) }) }) }),
327
- user?._id || user?.uid ? /* @__PURE__ */ jsxs(Fragment, { children: [
328
+ hasLoggedInSession(user) ? /* @__PURE__ */ jsxs(Fragment, { children: [
328
329
  !signupFlow && /* @__PURE__ */ jsx(MobileMenuPart, { withPadding: true, flexColumn: true, borderTop: true, children: /* @__PURE__ */ jsx(MenuNav, { mobile: true, children: /* @__PURE__ */ jsx("ul", { children: isAdmin ? /* @__PURE__ */ jsx(Fragment, { children: isVentureDashboard ? /* @__PURE__ */ jsx(MobileMenuItem, { children: /* @__PURE__ */ jsx("a", { href: "/settings", children: "Settings" }) }) : /* @__PURE__ */ jsx(MobileMenuItem, { children: /* @__PURE__ */ jsx(
329
330
  "a",
330
331
  {
@@ -8,6 +8,7 @@ import { IoniconsStyles } from "../../styles/ioniconsStyles.js";
8
8
  import { getConfig } from "../../runtime-config.js";
9
9
  import { navigateToHref } from "../../routing/navigate-app.js";
10
10
  import { withRouter } from "../../utils/withRouter.js";
11
+ import { hasLoggedInSession } from "../../utils/user-identity.js";
11
12
  class MainMenuClass extends PureComponent {
12
13
  state = {
13
14
  isSettingsActive: false,
@@ -60,7 +61,7 @@ class MainMenuClass extends PureComponent {
60
61
  letterSpacing: "1.5px",
61
62
  cursor: "pointer"
62
63
  };
63
- const isUserLogged = !!user?._id || user?.uid;
64
+ const isUserLogged = hasLoggedInSession(user);
64
65
  return /* @__PURE__ */ jsxs(StyledMainMenu, { children: [
65
66
  /* @__PURE__ */ jsx(IoniconsStyles, {}),
66
67
  /* @__PURE__ */ jsx(Collapse, { isOpened: isMenuActive && isUserLogged, hasNestedCollapse: true, children: /* @__PURE__ */ jsxs(MainMenuContainer, { children: [
package/dist/config.js CHANGED
@@ -1,4 +1,4 @@
1
- import { initFirebase } from "./firebase-config.js";
1
+ import { isValidFirebaseConfig, initFirebase } from "./firebase-config.js";
2
2
  import axiosInstance from "./model/axios.js";
3
3
  import axiosInstance$1 from "./model/axiosPublic.js";
4
4
  import { assignRuntimeConfig } from "./runtime-config.js";
@@ -12,9 +12,14 @@ function configure(config = {}) {
12
12
  if (config.baseUrlPublic != null) {
13
13
  axiosInstance$1.defaults.baseURL = config.baseUrlPublic;
14
14
  }
15
- if (config.firebase) {
16
- _lastFirebaseConfig = config.firebase;
17
- initFirebase(config.firebase);
15
+ if (Object.prototype.hasOwnProperty.call(config, "firebase")) {
16
+ const fb = config.firebase;
17
+ if (fb != null && isValidFirebaseConfig(fb)) {
18
+ _lastFirebaseConfig = fb;
19
+ initFirebase(fb);
20
+ } else {
21
+ _lastFirebaseConfig = null;
22
+ }
18
23
  }
19
24
  }
20
25
  function getLastFirebaseConfig() {
@@ -9,14 +9,15 @@ import { configure } from "../config.js";
9
9
  import { getPlatformURL, getConfig } from "../runtime-config.js";
10
10
  import { isAlreadyOnOnboardingFlow } from "../utils/app-urls.js";
11
11
  import { Text } from "../components/Text/Text.styles.js";
12
- import { getFirebaseAuth } from "../firebase-config.js";
13
12
  import { Auth } from "./Auth.js";
14
13
  import { DEFAULT_TOKEN_EXPIRY_MS } from "./Auth.js";
14
+ import { getFirebaseAuth, isValidFirebaseConfig } from "../firebase-config.js";
15
15
  import { ConfirmModal as ConfirmModalComponent } from "../components/ConfirmModal/ConfirmModal.js";
16
16
  import avatarPlaceholder from "../static/images/avatar-placeholder.png.js";
17
17
  import { signOut, getMultiFactorResolver, PhoneMultiFactorGenerator, TotpMultiFactorGenerator, multiFactor } from "firebase/auth";
18
18
  import { navigateToHref } from "../routing/navigate-app.js";
19
19
  const AuthContext = React__default.createContext();
20
+ const FALLBACK_AUTH_CONTEXT_VALUE = { user: null, isFetchingUser: false };
20
21
  const INACTIVITY_TIME_MS = 5 * 60 * 1e3;
21
22
  const INACTIVITY_EVENTS = ["mousemove", "keydown", "click", "scroll", "touchstart"];
22
23
  class AuthProviderClass extends Component {
@@ -338,7 +339,10 @@ class AuthProviderClass extends Component {
338
339
  this.setState({ waitingFor2fa: false, firebaseError: null });
339
340
  };
340
341
  patchUserObject = (user, firebaseUser) => {
341
- if (!user || !firebaseUser) return;
342
+ if (!user) return;
343
+ if (!firebaseUser) {
344
+ return { ...user, active: !!user.emailVerified };
345
+ }
342
346
  const merged = Object.assign(Object.create(Object.getPrototypeOf(firebaseUser)), firebaseUser, user);
343
347
  merged.active = merged.emailVerified;
344
348
  return merged;
@@ -364,11 +368,6 @@ class AuthProviderClass extends Component {
364
368
  user: null,
365
369
  firebaseUser: null
366
370
  });
367
- if (typeof console !== "undefined" && console.debug) {
368
- console.debug(
369
- "[@stokr/components-library] getUser() skipped: no access token. If you expected a session, ensure config.cookieDomain matches this origin (e.g. omit or use empty for localhost)."
370
- );
371
- }
372
371
  return;
373
372
  }
374
373
  this.setState({
@@ -385,7 +384,20 @@ class AuthProviderClass extends Component {
385
384
  let firebaseUser = existingFirebaseUser;
386
385
  if (!firebaseUser) {
387
386
  const customToken = tokenRes?.customToken ?? tokenRes?.custom_token ?? tokenRes?.token ?? tokenRes;
388
- firebaseUser = await Auth.signInWithToken(customToken);
387
+ try {
388
+ firebaseUser = await Auth.signInWithToken(customToken);
389
+ } catch (firebaseErr) {
390
+ const fbCode = firebaseErr?.code;
391
+ if (fbCode === "auth/internal-error" || fbCode === "auth/network-request-failed") {
392
+ if (typeof console !== "undefined" && console.warn) {
393
+ console.warn(
394
+ "[@stokr/components-library] Firebase signIn failed (" + fbCode + ") — session preserved. Add this domain to Firebase Console → Authentication → Authorized domains."
395
+ );
396
+ }
397
+ } else {
398
+ throw firebaseErr;
399
+ }
400
+ }
389
401
  }
390
402
  const user = this.patchUserObject(result.user, firebaseUser);
391
403
  this.checkUserIsValid(user);
@@ -409,12 +421,9 @@ class AuthProviderClass extends Component {
409
421
  const code = error?.code;
410
422
  const httpStatus = error?.response?.status;
411
423
  if (code === "auth/internal-error" || code === "auth/network-request-failed") {
412
- Auth.logout();
413
424
  if (typeof console !== "undefined" && console.warn) {
414
425
  console.warn(
415
- "[@stokr/components-library] getUser() failed with",
416
- code,
417
- "— session cleared. Ensure AuthProvider receives config.firebase for this origin and that the domain is authorized in Firebase Console (Authentication → Settings → Authorized domains)."
426
+ "[@stokr/components-library] getUser() encountered Firebase error (" + code + "). Ensure AuthProvider receives config.firebase and the domain is in Firebase Console → Authorized domains."
418
427
  );
419
428
  }
420
429
  return;
@@ -798,8 +807,23 @@ AuthProviderClass.propTypes = {
798
807
  /** Override access token cookie lifetime in ms (e.g. for Storybook). Production uses 1 hour. */
799
808
  accessTokenExpiryMs: PropTypes.number
800
809
  };
810
+ function resolveFirebaseConfigForGuard(props) {
811
+ if (props.config?.firebase != null) return props.config.firebase;
812
+ return getConfig("firebase");
813
+ }
814
+ function AuthProviderGuard(props) {
815
+ if (props.config) {
816
+ configure(props.config);
817
+ }
818
+ const firebase = resolveFirebaseConfigForGuard(props);
819
+ if (!isValidFirebaseConfig(firebase)) {
820
+ return /* @__PURE__ */ jsx(AuthContext.Provider, { value: FALLBACK_AUTH_CONTEXT_VALUE, children: props.children });
821
+ }
822
+ return /* @__PURE__ */ jsx(AuthProviderClass, { ...props });
823
+ }
824
+ AuthProviderGuard.propTypes = AuthProviderClass.propTypes;
801
825
  const AuthConsumer = AuthContext.Consumer;
802
- const AuthProvider = withRouter(AuthProviderClass);
826
+ const AuthProvider = withRouter(AuthProviderGuard);
803
827
  export {
804
828
  AuthConsumer,
805
829
  AuthContext,
@@ -4,7 +4,7 @@ import { getConfig } from "./runtime-config.js";
4
4
  const __vite_import_meta_env__ = {};
5
5
  let app = null;
6
6
  let auth = null;
7
- function isValidConfig(config) {
7
+ function isValidFirebaseConfig(config) {
8
8
  return config?.apiKey != null && String(config.apiKey).trim() !== "";
9
9
  }
10
10
  function getFirebaseAuth() {
@@ -12,7 +12,7 @@ function getFirebaseAuth() {
12
12
  }
13
13
  function initFirebase(configOverride) {
14
14
  const firebaseConfig = configOverride != null ? configOverride : getConfig("firebase");
15
- if (!isValidConfig(firebaseConfig)) {
15
+ if (!isValidFirebaseConfig(firebaseConfig)) {
16
16
  if (configOverride && typeof console !== "undefined" && console.warn) {
17
17
  console.warn(
18
18
  "[firebase-config] initFirebase() received a config with no valid apiKey. Ensure all VITE_FIREBASE_* variables are defined in your .env file and the dev server was restarted."
@@ -49,11 +49,12 @@ function initFirebase(configOverride) {
49
49
  }
50
50
  }
51
51
  }
52
- if (typeof __vite_import_meta_env__ !== "undefined" && isValidConfig(getConfig("firebase"))) {
52
+ if (typeof __vite_import_meta_env__ !== "undefined" && isValidFirebaseConfig(getConfig("firebase"))) {
53
53
  initFirebase();
54
54
  }
55
55
  export {
56
56
  auth,
57
57
  getFirebaseAuth,
58
- initFirebase
58
+ initFirebase,
59
+ isValidFirebaseConfig
59
60
  };
@@ -1,4 +1,4 @@
1
- const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false, "VITE_ADMIN_URL": "https://admin.stokr.info", "VITE_API_URL": "https://platform-api.stokr.info/api/v1", "VITE_BASE_URL_PUBLIC": "https://platform-api-no-auth.stokr.info/api/v1", "VITE_COOKIE_DOMAIN": "stokr.info", "VITE_DASHBOARD_URL": "https://dashboard.stokr.info", "VITE_FIREBASE_API_KEY": "AIzaSyBBp_3Romnfv--YpUuV0mJgDymvSp3oq0c", "VITE_FIREBASE_APP_ID": "1:568229412804:web:2391857e3e2a0b02346e91", "VITE_FIREBASE_AUTH_DOMAIN": "stokr-development-env.firebaseapp.com", "VITE_FIREBASE_MEASUREMENT_ID": "G-CP53SZVSMN", "VITE_FIREBASE_MESSAGING_SENDER_ID": "568229412804", "VITE_FIREBASE_PROJECT_ID": "stokr-development-env", "VITE_FIREBASE_STORAGE_BUCKET": "stokr-development-env.appspot.com", "VITE_MIXPANEL_TOKEN": "a7bb1e881f9b2600762fded84d8ce0ea", "VITE_ONBOARDING_URL": "https://signup.stokr.info", "VITE_PHOTO_API_URL": "https://platform-api.stokr.info/api/v1", "VITE_REGISTER_URL": "https://stokr.info/signup", "VITE_WEBSITE_DOMAIN": "stokr.info" };
1
+ const __vite_import_meta_env__ = { "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SSR": false, "VITE_ADMIN_URL": "https://admin.stokr.info", "VITE_API_URL": "https://platform-api.stokr.info/api/v1", "VITE_BASE_URL_PUBLIC": "https://platform-api-no-auth.stokr.info/api/v1", "VITE_COOKIE_DOMAIN": "localhost", "VITE_DASHBOARD_URL": "https://dashboard.stokr.info", "VITE_FIREBASE_API_KEY": "AIzaSyBBp_3Romnfv--YpUuV0mJgDymvSp3oq0c", "VITE_FIREBASE_APP_ID": "1:568229412804:web:2391857e3e2a0b02346e91", "VITE_FIREBASE_AUTH_DOMAIN": "stokr-development-env.firebaseapp.com", "VITE_FIREBASE_MEASUREMENT_ID": "G-CP53SZVSMN", "VITE_FIREBASE_MESSAGING_SENDER_ID": "568229412804", "VITE_FIREBASE_PROJECT_ID": "stokr-development-env", "VITE_FIREBASE_STORAGE_BUCKET": "stokr-development-env.appspot.com", "VITE_MIXPANEL_TOKEN": "a7bb1e881f9b2600762fded84d8ce0ea", "VITE_ONBOARDING_URL": "https://signup.stokr.info", "VITE_PHOTO_API_URL": "https://platform-api.stokr.info/api/v1", "VITE_REGISTER_URL": "https://stokr.info/signup", "VITE_WEBSITE_DOMAIN": "stokr.info" };
2
2
  const _overrides = {};
3
3
  const ENV_KEY_BY_CONFIG = {
4
4
  apiUrl: "VITE_API_URL",
@@ -0,0 +1,7 @@
1
+ function hasLoggedInSession(user) {
2
+ if (user == null || typeof user !== "object") return false;
3
+ return Boolean(user._id || user.uid);
4
+ }
5
+ export {
6
+ hasLoggedInSession
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stokr/components-library",
3
- "version": "3.0.27",
3
+ "version": "3.0.28",
4
4
  "description": "STOKR - Components Library",
5
5
  "author": "Bilal Hodzic <bilal@stokr.io>",
6
6
  "license": "MIT",