@openstack_dev/gatsby-theme-marketing-oif-core 1.0.33-beta.2 → 1.0.34-beta.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openstack_dev/gatsby-theme-marketing-oif-core",
3
- "version": "1.0.33-beta.2",
3
+ "version": "1.0.34-beta.4",
4
4
  "description": "Base theme for Marketing Sites",
5
5
  "author": "smarcet",
6
6
  "keywords": [
@@ -0,0 +1,50 @@
1
+ import React, { useEffect } from "react";
2
+ import { useSelector } from "react-redux";
3
+ import { doLoginBasicLogin } from "openstack-uicore-foundation/lib/security/methods";
4
+ import { getBackURL } from "../utils/url";
5
+
6
+ export default function AuthBootstrap() {
7
+ const isLoggedUser = useSelector(
8
+ (state) => state.loggedUserState.isLoggedUser
9
+ );
10
+
11
+ const checkLoginStatus = async () => {
12
+ try {
13
+ const response = await fetch("/oidc/session/whoami", {
14
+ method: "GET",
15
+ credentials: "same-origin"
16
+ });
17
+
18
+ if (response.ok) {
19
+ const data = await response.json();
20
+ if (
21
+ data.email &&
22
+ typeof data.email === "string" &&
23
+ /\S+@\S+\.\S+/.test(data.email)
24
+ ) {
25
+ doLoginBasicLogin(getBackURL(), data.email);
26
+ } else {
27
+ console.warn(
28
+ "Invalid or missing email in login response:",
29
+ data.email
30
+ );
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error(
35
+ "Failed to check login status. Possible network error or invalid response.",
36
+ {
37
+ error,
38
+ attemptedUrl: "/oidc/session/whoami"
39
+ }
40
+ );
41
+ }
42
+ };
43
+
44
+ useEffect(() => {
45
+ if (!isLoggedUser) checkLoginStatus();
46
+ }, [isLoggedUser]);
47
+
48
+
49
+ return null;
50
+ }
@@ -1,46 +1,39 @@
1
1
  import React from "react";
2
2
  import { Link as GatsbyLink } from "gatsby";
3
- // Since DOM elements <a> cannot receive activeClassName
4
- // and partiallyActive, destructure the prop here and
5
- // pass it only to GatsbyLink
6
- function Link({ children, to, activeClassName, partiallyActive, ...other }) {
7
- // Tailor the following test to your environment.
8
3
 
9
- const email = /\S+@\S+\.\S+/.test(to);
10
- const isAbsoluteUrl = /^(https?:)?\/\//i.test(to);
11
- const isHash = to.startsWith("#");
4
+ /* global __PATH_PREFIX__ */
12
5
 
13
- // Gatsby pathPrefix at runtime ("" in dev, "/marketplace" in your build)
14
- const prefix =
15
- typeof __PATH_PREFIX__ !== "undefined" && __PATH_PREFIX__
16
- ? __PATH_PREFIX__
17
- : "";
6
+ const normalizePrefix = (p) => {
7
+ if (!p) return "";
8
+ const trimmed = String(p).replace(/\/+$/, ""); // remove trailing slash
9
+ return trimmed === "/" ? "" : trimmed; // Gatsby uses "" for root
10
+ };
18
11
 
19
- console.log(`Link::render prefix ${prefix}`);
20
- // Internal for Gatsby routing *only if*:
21
- // - it’s a single-slash path
22
- // - and it’s inside the current prefix (or there is no prefix)
23
- const isSingleSlashPath = /^\/(?!\/)/.test(to);
12
+ const isAbsoluteUrl = (url = "") => /^(https?:)?\/\//i.test(url);
13
+ const isSingleSlashPath = (url = "") => /^\/(?!\/)/.test(url);
24
14
 
25
- // If we're running with /marketplace prefix, only /marketplace/* should be Gatsby-internal
26
- const internal =
27
- isSingleSlashPath &&
28
- (!prefix || to === prefix || to.startsWith(`${prefix}/`));
15
+ const stripPrefix = (path, prefix) => {
16
+ if (!prefix) return path;
17
+ if (path === prefix) return "/";
18
+ if (path.startsWith(`${prefix }/`)) return path.slice(prefix.length) || "/";
19
+ return path;
20
+ };
29
21
 
30
- // Use Gatsby Link for internal links, and <a> for others
31
- if (internal) {
32
- return (
33
- <GatsbyLink
34
- to={to}
35
- activeClassName={activeClassName}
36
- partiallyActive={partiallyActive}
37
- {...other}
38
- >
39
- {children}
40
- </GatsbyLink>
41
- );
42
- }
22
+ function Link({
23
+ children,
24
+ to = "",
25
+ activeClassName,
26
+ partiallyActive,
27
+ ...other
28
+ }) {
29
+ const email = /\S+@\S+\.\S+/.test(to);
30
+ const hash = to.startsWith("#");
43
31
 
32
+ const rawPrefix =
33
+ typeof __PATH_PREFIX__ !== "undefined" ? __PATH_PREFIX__ : "";
34
+ const prefix = normalizePrefix(rawPrefix);
35
+
36
+ // Email
44
37
  if (email) {
45
38
  const href = /^mailto:/.test(to) ? to : `mailto:${to}`;
46
39
  return (
@@ -50,8 +43,8 @@ function Link({ children, to, activeClassName, partiallyActive, ...other }) {
50
43
  );
51
44
  }
52
45
 
53
- // For absolute URLs keep new tab behavior
54
- if (isAbsoluteUrl) {
46
+ // Absolute URL -> new tab
47
+ if (isAbsoluteUrl(to)) {
55
48
  return (
56
49
  <a href={to} target="_blank" rel="noreferrer" {...other}>
57
50
  {children}
@@ -59,8 +52,44 @@ function Link({ children, to, activeClassName, partiallyActive, ...other }) {
59
52
  );
60
53
  }
61
54
 
62
- // Hash or base-site root paths like /software should be same-tab
63
- if (isHash || isSingleSlashPath) {
55
+ // Hash -> same tab
56
+ if (hash) {
57
+ return (
58
+ <a href={to} {...other}>
59
+ {children}
60
+ </a>
61
+ );
62
+ }
63
+
64
+ // Not a normal "/path" -> default anchor same tab
65
+ if (!isSingleSlashPath(to)) {
66
+ return (
67
+ <a href={to} {...other}>
68
+ {children}
69
+ </a>
70
+ );
71
+ }
72
+
73
+ // If we are running with a prefix (/__PATH_PREFIX__):
74
+ // - Links already under /__PATH_PREFIX__ are INTERNAL, but must be de-prefixed for GatsbyLink
75
+ // - Links outside /__PATH_PREFIX__ (e.g. /software) should be plain <a> to avoid prefixing
76
+ if (prefix) {
77
+ const isPrefixed = to === prefix || to.startsWith(`${prefix}/`);
78
+ if (isPrefixed) {
79
+ const normalizedTo = stripPrefix(to, prefix); // "/marketplace/distros" -> "/distros"
80
+ return (
81
+ <GatsbyLink
82
+ to={normalizedTo}
83
+ activeClassName={activeClassName}
84
+ partiallyActive={partiallyActive}
85
+ {...other}
86
+ >
87
+ {children}
88
+ </GatsbyLink>
89
+ );
90
+ }
91
+
92
+ // base site path
64
93
  return (
65
94
  <a href={to} {...other}>
66
95
  {children}
@@ -68,11 +97,16 @@ function Link({ children, to, activeClassName, partiallyActive, ...other }) {
68
97
  );
69
98
  }
70
99
 
71
- // Fallback
100
+ // No prefix site: normal Gatsby internal
72
101
  return (
73
- <a href={to} target="_blank" rel="noreferrer" {...other}>
102
+ <GatsbyLink
103
+ to={to}
104
+ activeClassName={activeClassName}
105
+ partiallyActive={partiallyActive}
106
+ {...other}
107
+ >
74
108
  {children}
75
- </a>
109
+ </GatsbyLink>
76
110
  );
77
111
  }
78
112
 
@@ -4,6 +4,7 @@ import { PersistGate } from "redux-persist/integration/react";
4
4
  import { CacheProvider } from "@emotion/react";
5
5
  import { store, persistor } from "./store";
6
6
  import createEmotionCache from "../utils/createEmotionCache";
7
+ import AuthBootstrap from "../components/AuthBootstrap";
7
8
 
8
9
  export function ReduxWrapper({ element }) {
9
10
  return (
@@ -18,6 +19,7 @@ export function ReduxWrapperWithCacheProvider({ element }) {
18
19
  return (
19
20
  <CacheProvider value={cache}>
20
21
  <Provider store={store}>
22
+ <AuthBootstrap />
21
23
  <PersistGate persistor={persistor}>{() => element}</PersistGate>
22
24
  </Provider>
23
25
  </CacheProvider>
@@ -0,0 +1,7 @@
1
+ export const getBackURL = () => {
2
+ let backUrl = "/";
3
+ if (typeof window !== "undefined") {
4
+ backUrl = window.location.pathname;
5
+ }
6
+ return backUrl;
7
+ };