diff --git a/.github/workflows/build-and-push.yaml b/.github/workflows/build-and-push.yaml
index 363a7017..b3b04126 100644
--- a/.github/workflows/build-and-push.yaml
+++ b/.github/workflows/build-and-push.yaml
@@ -75,12 +75,20 @@ jobs:
name: Get deploy tag
id: deploy-tag
run: |
- # Parse container image tag to deploy
- full_tag=$(echo "$DOCKER_METADATA_OUTPUT_JSON" | jq -r '.tags[] | limit(1; select(. | test(":sha-|:v.")))')
- echo "Will use tag \"$full_tag\" for deployment."
- echo image_tag=$(echo "$full_tag" | cut -f2 -d:) >> "$GITHUB_OUTPUT"
- echo image_name=$(echo "$full_tag" | cut -f1 -d:) >> "$GITHUB_OUTPUT"
- echo full_tag=$full_tag >> "$GITHUB_OUTPUT"
+ # Determine environment to deploy to
+ if ${{ github.ref == 'master' || github.base_ref == 'master'}}; then
+ environment_name="int"
+ credentials_json='${{ secrets.SKYVIEWER_INT_SERVICE_ACCOUNT }}'
+ elif ${{ github.ref_type == 'tag'}}; then
+ environment_name="prod"
+ credentials_json='${{ secrets.PIPELINE_EPO_PROD_PROJECT }}'
+ else
+ environment_name="dev"
+ credentials_json='${{ secrets.DEV_SA_KEY }}'
+ fi
+ echo environment_name=$environment_name >> "$GITHUB_OUTPUT"
+ echo credentials_json=$credentials_json >> "$GITHUB_OUTPUT"
+
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
diff --git a/.github/workflows/dev-pull-request.yaml b/.github/workflows/dev-pull-request.yaml
index 7388bdd0..ae416f8d 100644
--- a/.github/workflows/dev-pull-request.yaml
+++ b/.github/workflows/dev-pull-request.yaml
@@ -39,6 +39,7 @@ jobs:
--build-arg NEXT_PUBLIC_DEBUG_LOGGING=false \
--build-arg CLOUD_ENV=DEV \
--build-arg NEXT_PUBLIC_GOOGLE_APP_ID=688095955960-t0fpaj4ec3gh5vsr9lhg8govapk2oeo9.apps.googleusercontent.com \
+ --build-arg GOOGLE_APP_SECRET=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 \
--build-arg NEXT_PUBLIC_CONTACT_FORM_POST_URL=https://api-dev.rubinobs.com/actions/contact-form/send \
--build-arg NEXT_PUBLIC_PLAUSIBLE_DOMAIN= \
--build-arg NEXT_PREVIEW_SLUG=preview-in-craft-cms \
diff --git a/.github/workflows/dev-push.yaml b/.github/workflows/dev-push.yaml
index dca62ef0..d782dc72 100644
--- a/.github/workflows/dev-push.yaml
+++ b/.github/workflows/dev-push.yaml
@@ -33,6 +33,7 @@ jobs:
--build-arg CLOUD_ENV=DEV \
--build-arg NEXT_PUBLIC_BASE_URL=https://dev.rubinobs.com \
--build-arg NEXT_PUBLIC_GOOGLE_APP_ID=688095955960-t0fpaj4ec3gh5vsr9lhg8govapk2oeo9.apps.googleusercontent.com \
+ --build-arg GOOGLE_APP_SECRET=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 \
--build-arg NEXT_PUBLIC_CONTACT_FORM_POST_URL=https://api-dev.rubinobs.com/actions/contact-form/send \
--build-arg NEXT_PUBLIC_PLAUSIBLE_DOMAIN= \
--build-arg NEXT_PREVIEW_SLUG=preview-in-craft-cms \
diff --git a/.github/workflows/master-pr.yaml b/.github/workflows/master-pr.yaml
index dc3777cb..917994a8 100644
--- a/.github/workflows/master-pr.yaml
+++ b/.github/workflows/master-pr.yaml
@@ -38,7 +38,8 @@ jobs:
--build-arg NEXT_PUBLIC_DEBUG_LOGGING=false \
--build-arg CLOUD_ENV=INT \
--build-arg NEXT_PUBLIC_BASE_URL=https://int.rubinobs.dev \
- --build-arg NEXT_PUBLIC_GOOGLE_APP_ID=688095955960-t0fpaj4ec3gh5vsr9lhg8govapk2oeo9.apps.googleusercontent.com \
+ --build-arg NEXT_PUBLIC_GOOGLE_APP_ID=422617727806-q7opitpsisom3fekpplsh8b77s0oe6n2.apps.googleusercontent.com \
+ --build-arg GOOGLE_APP_SECRET=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 \
--build-arg NEXT_PUBLIC_CONTACT_FORM_POST_URL=https://api-int.rubinobs.dev/actions/contact-form/send \
--build-arg NEXT_PUBLIC_PLAUSIBLE_DOMAIN= \
--build-arg NEXT_PREVIEW_SLUG=preview-in-craft-cms \
diff --git a/.github/workflows/master-push.yaml b/.github/workflows/master-push.yaml
index f9839403..ccec1b63 100644
--- a/.github/workflows/master-push.yaml
+++ b/.github/workflows/master-push.yaml
@@ -32,7 +32,8 @@ jobs:
--build-arg EDC_LOGGER_API_URL=https://us-central1-skyviewer.cloudfunctions.net/edc-logger \
--build-arg NEXT_PUBLIC_DEBUG_LOGGING=false \
--build-arg CLOUD_ENV=INT \
- --build-arg NEXT_PUBLIC_GOOGLE_APP_ID=688095955960-t0fpaj4ec3gh5vsr9lhg8govapk2oeo9.apps.googleusercontent.com \
+ --build-arg NEXT_PUBLIC_GOOGLE_APP_ID=422617727806-q7opitpsisom3fekpplsh8b77s0oe6n2.apps.googleusercontent.com \
+ --build-arg GOOGLE_APP_SECRET=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 \
--build-arg NEXT_PUBLIC_CONTACT_FORM_POST_URL=https://api-int.rubinobs.dev/actions/contact-form/send \
--build-arg NEXT_PUBLIC_PLAUSIBLE_DOMAIN= \
--build-arg NEXT_PREVIEW_SLUG=preview-in-craft-cms \
diff --git a/.github/workflows/prod-push.yaml b/.github/workflows/prod-push.yaml
index f1eaa181..f7209e06 100644
--- a/.github/workflows/prod-push.yaml
+++ b/.github/workflows/prod-push.yaml
@@ -39,6 +39,7 @@ jobs:
--build-arg NEXT_PUBLIC_DEBUG_LOGGING=false \
--build-arg CLOUD_ENV=PROD \
--build-arg NEXT_PUBLIC_GOOGLE_APP_ID=596747551410-vcqlrp7erg5c5gm0dkvc0k21mgi0ilg0.apps.googleusercontent.com \
+ --build-arg GOOGLE_APP_SECRET=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 \
--build-arg NEXT_PUBLIC_CONTACT_FORM_POST_URL=https://api.rubinobs.org/actions/contact-form/send \
--build-arg NEXT_PUBLIC_PLAUSIBLE_DOMAIN=rubinobservatory.org,all.epo.sites \
--build-arg NEXT_PREVIEW_SLUG=preview-in-craft-cms \
diff --git a/components/atomic/Button/patterns/GoogleSSOButton.js b/components/atomic/Button/patterns/GoogleSSOButton.js
new file mode 100644
index 00000000..2cf2df02
--- /dev/null
+++ b/components/atomic/Button/patterns/GoogleSSOButton.js
@@ -0,0 +1,52 @@
+import PropTypes from "prop-types";
+import { useGoogleLogin } from "@react-oauth/google";
+import { useRouter } from "next/router";
+import { useAuthenticationContext } from "@/contexts/Authentication";
+import SSOButton from "./SSOButton";
+
+export default function GoogleSSOButton({ children, ...buttonProps }) {
+ const { authenticateWithGoogle } = useAuthenticationContext();
+ const { query, push, asPath, pathname } = useRouter();
+ const goToGoogleSignIn = useGoogleLogin({
+ state: asPath,
+ onSuccess: (response) => {
+ push(
+ { pathname: asPath.split("?")[0], query: { sso: true } },
+ undefined,
+ {
+ shallow: true,
+ }
+ );
+ fetch("/api/authGoogle", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ code: response.code }),
+ })
+ .then((res) => res.json())
+ .then((data) => {
+ authenticateWithGoogle(data);
+ })
+ .catch(console.error);
+ },
+ onError: (error) => {
+ console.error(error);
+ },
+ flow: "auth-code",
+ });
+
+ return (
+
+ {children}
+
+ );
+}
+
+GoogleSSOButton.propTypes = {
+ children: PropTypes.node,
+ service: PropTypes.oneOf(["google", "facebook", "email"]),
+};
diff --git a/components/atomic/index.js b/components/atomic/index.js
index fc309792..181f6fd7 100644
--- a/components/atomic/index.js
+++ b/components/atomic/index.js
@@ -1,4 +1,5 @@
export { default as SSOButton } from "./Button/patterns/SSOButton";
+export { default as GoogleSSOButton } from "./Button/patterns/GoogleSSOButton";
export { default as EarlyAccess } from "./Flag/patterns/EarlyAccess";
export { default as Tile } from "./Tile";
export { default as InvestigationTile } from "./Tile/patterns/InvestigationTile";
diff --git a/components/auth/AuthorizePage/index.js b/components/auth/AuthorizePage/index.js
index cc0b3358..8c6295ba 100644
--- a/components/auth/AuthorizePage/index.js
+++ b/components/auth/AuthorizePage/index.js
@@ -15,7 +15,8 @@ const AUTHORIZED_TYPES = {
};
function isAuthorized(typeHandle, user, status) {
- if (typeHandle === "educatorPages") return user?.group === "educators";
+ if (typeHandle === "educatorPages")
+ return user?.group === "educators" && status === "active";
if (typeHandle === "userProfilePage") return !!user && status === "active";
return false;
}
diff --git a/components/dynamic/EventList/index.js b/components/dynamic/EventList/index.js
index 6230ac49..62176cd7 100644
--- a/components/dynamic/EventList/index.js
+++ b/components/dynamic/EventList/index.js
@@ -42,6 +42,7 @@ const EventList = ({
endDate,
description,
id,
+ hero,
image,
eventType,
registrationCloseDate,
@@ -82,7 +83,7 @@ const EventList = ({
}
: null
}
- image={image?.[0]}
+ image={image?.[0] || hero?.[0]}
link={uri}
pretitle={
gridType === "events" && eventType?.[0]?.title
diff --git a/components/dynamic/JobList/index.js b/components/dynamic/JobList/index.js
index 1bda97d7..def7363a 100644
--- a/components/dynamic/JobList/index.js
+++ b/components/dynamic/JobList/index.js
@@ -59,7 +59,8 @@ const JobList = ({
);
// logic for open/closed
- const checkOpen = checkIfBetweenDates(openDate, closeDate)
+ let checkOpen = "open";
+ checkOpen = checkIfBetweenDates(openDate, closeDate)
? "open"
: "closed";
const lock = checkOpen === "open" ? "LockOpen" : "LockClosed";
diff --git a/components/dynamic/NewsList/index.js b/components/dynamic/NewsList/index.js
index e349968d..3d324c3c 100644
--- a/components/dynamic/NewsList/index.js
+++ b/components/dynamic/NewsList/index.js
@@ -51,6 +51,7 @@ const NewsList = ({
description,
subtitle,
id,
+ hero,
image,
images: releaseImages,
newsAssets,
@@ -70,7 +71,11 @@ const NewsList = ({
}
: null
}
- image={image?.[0] || makeReleaseFeature(releaseImages)?.[0]}
+ image={
+ image?.[0] ||
+ makeReleaseFeature(releaseImages)?.[0] ||
+ hero?.[0]
+ }
isFeature={canShowFeatured && page === 1 && i === 0}
link={uri}
pretitle={
diff --git a/components/dynamic/RelatedList/index.js b/components/dynamic/RelatedList/index.js
index 4de8c283..b76f95a3 100644
--- a/components/dynamic/RelatedList/index.js
+++ b/components/dynamic/RelatedList/index.js
@@ -30,17 +30,19 @@ const RelatedList = ({
<>
{entries?.length > 0 && (
- {entries.map(({ id, description, image, title, uri }, i) => (
-
- ))}
+ {entries.map(
+ ({ id, description, hero, image, title, uri }, i) => (
+
+ )
+ )}
)}
>
diff --git a/components/modal/RegisterModal/JoinForm/index.js b/components/modal/RegisterModal/JoinForm/index.js
index 18600b1e..2c49a780 100644
--- a/components/modal/RegisterModal/JoinForm/index.js
+++ b/components/modal/RegisterModal/JoinForm/index.js
@@ -2,7 +2,7 @@ import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { Link as BaseLink } from "@rubin-epo/epo-react-lib";
-import { SSOButton } from "@/components/atomic";
+import { GoogleSSOButton, SSOButton } from "@/components/atomic";
import useAuthModal from "@/hooks/useAuthModal";
import { useAuthenticationContext } from "@/contexts/Authentication";
import AuthModal from "../../AuthModal";
@@ -14,7 +14,7 @@ export default function JoinForm({ onEmailSignup }) {
const {
pendingGroup,
setPendingGroup,
- goToGoogleSignIn,
+ // goToGoogleSignIn,
goToFacebookSignIn,
} = useAuthenticationContext();
@@ -47,9 +47,9 @@ export default function JoinForm({ onEmailSignup }) {
*/}
-
+
{t("join.continue_with_google")}
-
+
{/*
*/}
-
- {t("sign_in.continue_with_google")}
-
+
+ {t("join.continue_with_google")}
+
{/*
{t("sign_in.continue_with_facebook")}
*/}
diff --git a/components/templates/NewsPage/MediaAssets.js b/components/templates/NewsPage/MediaAssets.js
index 705bc454..aec1289c 100644
--- a/components/templates/NewsPage/MediaAssets.js
+++ b/components/templates/NewsPage/MediaAssets.js
@@ -1,7 +1,7 @@
import PropTypes from "prop-types";
import Link from "next/link";
import { useTranslation } from "react-i18next";
-import { ResponsiveImage } from "@rubin-epo/epo-react-lib";
+import { ResponsiveImage, Figure } from "@rubin-epo/epo-react-lib";
import ReleaseAssets from "./ReleaseAssets";
import * as Styled from "./styles";
@@ -15,11 +15,12 @@ export default function MediaAssets({
if (!contentBlockAssets && !releaseImages && !releaseVideos) return null;
if (
- contentBlockAssets?.length <= 0 &&
- releaseImages?.length <= 0 &&
- releaseVideos?.length <= 0
+ contentBlockAssets?.length === 0 &&
+ releaseImages?.length === 0 &&
+ releaseVideos?.length === 0
)
return null;
+
return (
{t(`media`)}
@@ -27,7 +28,9 @@ export default function MediaAssets({
if (asset.image?.[0].url) {
return (
-
+
+
+
);
}
diff --git a/components/templates/NewsPage/NewsAside.js b/components/templates/NewsPage/NewsAside.js
index 096e79de..e325c47a 100644
--- a/components/templates/NewsPage/NewsAside.js
+++ b/components/templates/NewsPage/NewsAside.js
@@ -1,30 +1,32 @@
import PropTypes from "prop-types";
import Link from "next/link";
-import { ResponsiveImage, IconComposer } from "@rubin-epo/epo-react-lib";
+import {
+ ResponsiveImage,
+ IconComposer,
+ Figure,
+} from "@rubin-epo/epo-react-lib";
import Tags from "./Tags";
import MediaAssets from "./MediaAssets";
import * as Styled from "./styles";
export default function NewsAside({
- newsAssets,
+ manualAssets,
contentBlockAssets,
releaseImages,
releaseVideos,
tags,
rootHomeLink,
}) {
- // This sets up the automatic media grabber -- if there are no manual media set
- let manualMedia = false;
// This adds the document icon from the designs, if there is a text-style link near the start.
- let manualDoc = newsAssets.some(
+ let manualDoc = manualAssets.some(
(a, i) => i < 4 && (a.textLink?.length > 0 || a.externalLink?.length > 0)
);
return (
- {newsAssets?.length > 0 && (
+ {manualAssets?.length > 0 && (
- {newsAssets.map((a, i) => {
+ {manualAssets.map((a, i) => {
if (a.assetHeader) {
return (
@@ -53,14 +55,14 @@ export default function NewsAside({
);
} else if (a.image?.length > 0) {
- manualMedia = true;
return (
-
-
-
+
+
+
+
+
);
} else if (a.galleryItem?.length > 0) {
- manualMedia = true;
if (a.galleryItem[0].uri) {
return (
block.typeHandle === "image"
+ const manualAssets = [];
+ const heroBlock =
+ hero?.length > 0
+ ? {
+ id: id + "hero",
+ typeHandle: "image",
+ image: hero,
+ caption: heroCaption,
+ }
+ : null;
+ const mediaContentBlocks = [...contentBlocksNews].filter(
+ (block) => block.typeHandle === "image" || block.typeHandle === "video"
);
+ newsAssets.forEach((a, i) => {
+ if (a.image?.length > 0) {
+ // If there are manually added news assets combine them with the content block media assets
+ mediaContentBlocks.push({
+ id: id + i,
+ typeHandle: "image",
+ image: a.image,
+ caption: a.caption,
+ });
+ } else {
+ manualAssets.push(a);
+ }
+ });
+ // If there is a hero then combine it with the content block media assets
+ if (heroBlock) mediaContentBlocks.unshift(heroBlock);
+
+ // Only show the aside if there are news assets
const showAside =
- newsAssets?.length > 0 ||
- imageContentBlocks?.length > 0 ||
+ manualAssets?.length > 0 ||
+ mediaContentBlocks?.length > 0 ||
releaseImages?.length > 0 ||
releaseVideos?.length > 0 ||
postTags?.length > 0;
@@ -77,8 +104,8 @@ export default function NewsPage({ data }) {
)}
{showAside && (
{
- const ssoModalUrl = { pathname: "/", query: { sso: true } };
- push(ssoModalUrl, undefined, {
- shallow: true,
- });
- // eslint-disable-next-line no-console
- console.log("onSuccess", response, "onSuccess");
- authenticateWithGoogle({ idToken: response.tokenId });
- },
- onFailure: (error) => {
- // eslint-disable-next-line no-console
- console.log("onFailure", error, "onFailure");
- console.error(error);
- },
- });
-
useEffect(() => {
// TODO: cancel promise if component unmounts first
(async () => await maybeRefreshToken())();
@@ -442,8 +422,8 @@ export default function useAuthentication(data) {
forgotPassword,
setPassword,
activateUser,
- goToGoogleSignIn,
goToFacebookSignIn,
+ authenticateWithGoogle,
fetchUserData,
requestAccountDeletion,
};
diff --git a/lib/api/fragments/content-blocks.js b/lib/api/fragments/content-blocks.js
index d3fa7216..2fe28d0a 100644
--- a/lib/api/fragments/content-blocks.js
+++ b/lib/api/fragments/content-blocks.js
@@ -342,6 +342,11 @@ export const relatedContentFragment = `
uri
... on pages_pages_Entry {
description
+ hero {
+ ...on heroes_Asset {
+ ${getImageFields("crop", 900, 550)}
+ }
+ }
image: featuredImage {
...on contentImages_Asset {
${getImageFields("crop", 900, 550)}
@@ -350,11 +355,16 @@ export const relatedContentFragment = `
}
...on news_post_Entry {
description: teaser
- image: hero {
+ hero {
...on heroes_Asset {
${getImageFields("crop", 900, 550)}
}
}
+ image: featuredImage {
+ ...on contentImages_Asset {
+ ${getImageFields("crop", 900, 550)}
+ }
+ }
}
...on investigations_investigation_Entry {
uri
@@ -711,8 +721,8 @@ export const relatedContentNewsFragment = `
...on news_post_Entry {
date
description: teaser
- image: hero {
- ...on heroes_Asset {
+ image: featuredImage {
+ ...on contentImages_Asset {
${getImageFields("crop", 900, 550)}
}
}
diff --git a/lib/api/fragments/event.js b/lib/api/fragments/event.js
index 09c383ae..0d67b025 100644
--- a/lib/api/fragments/event.js
+++ b/lib/api/fragments/event.js
@@ -14,11 +14,16 @@ export const eventFragment = `
startDate
endDate: date
description
- image: hero {
+ hero {
...on heroes_Asset {
${getImageFields("crop", 400, 400)}
}
}
+ image: featuredImage {
+ ...on contentImages_Asset {
+ ${getImageFields("crop", 400, 400)}
+ }
+ }
eventType {
id
title
@@ -48,8 +53,8 @@ export const eventFragmentFull = `
${getImageFields("crop", 1920, 1067)}
}
}
- featuredImage: hero {
- ...on heroes_Asset {
+ featuredImage {
+ ...on contentImages_Asset {
${getImageFields("crop", 800, 800)}
}
}
diff --git a/lib/api/fragments/news-post.js b/lib/api/fragments/news-post.js
index c8039dc7..c4a75c2f 100644
--- a/lib/api/fragments/news-post.js
+++ b/lib/api/fragments/news-post.js
@@ -11,11 +11,16 @@ export const newsPostFragment = `
dateCreated
description: teaser
pressReleaseId
- image: hero {
+ hero {
...on heroes_Asset {
${getImageFields("crop", 900, 550)}
}
}
+ image: featuredImage {
+ ...on contentImages_Asset {
+ ${getImageFields("crop", 900, 550)}
+ }
+ }
postType {
id
title
@@ -58,8 +63,8 @@ export const newsPostFragmentFull = `
}
}
heroCaption: captionRichText
- featuredImage: hero {
- ...on heroes_Asset {
+ featuredImage {
+ ...on contentImages_Asset {
${getImageFields("crop", 800, 800)}
}
}
@@ -83,6 +88,7 @@ export const newsPostFragmentFull = `
${getImageFields("crop", 900, 550)}
}
}
+ caption
}
... on newsAssets_galleryItem_BlockType {
galleryItem {
diff --git a/package.json b/package.json
index 9a686b8b..75f7166a 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
"@headlessui/react": "^1.6.6",
"@influxdata/influxdb-client": "^1.33.2",
"@popperjs/core": "^2.11.5",
+ "@react-oauth/google": "^0.12.1",
"@rubin-epo/epo-react-lib": "^1.2.9",
"add": "^2.0.6",
"classnames": "^2.3.1",
@@ -68,6 +69,7 @@
"feed": "^4.2.2",
"focus-trap": "^7.0.0",
"focus-visible": "^5.1.0",
+ "google-auth-library": "^9.6.3",
"graphql": "^16.5.0",
"graphql-request": "^5.0.0",
"hoist-non-react-statics": "^3.3.2",
@@ -79,7 +81,6 @@
"npm-run-all": "^4.1.5",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-google-login": "^5.2.2",
"react-hook-form": "^7.33.1",
"react-i18next": "^12.0.0",
"react-is": "^18.2.0",
diff --git a/pages/[[...uriSegments]].js b/pages/[[...uriSegments]].js
index e49badeb..a23ce0c6 100644
--- a/pages/[[...uriSegments]].js
+++ b/pages/[[...uriSegments]].js
@@ -1,4 +1,5 @@
import PropTypes from "prop-types";
+import { GoogleOAuthProvider } from "@react-oauth/google";
import { getGlobalData } from "@/api/global";
import { getAllEntries } from "@/api/entries";
import { getEntryDataByUri, getEntrySectionTypeByUri } from "@/api/entry";
@@ -57,6 +58,7 @@ function logNextDir() {
});
}
+const GOOGLE_APP_ID = process.env.NEXT_PUBLIC_GOOGLE_APP_ID;
export default function Page({ section, globalData, ...entryProps }) {
globalData.localeInfo.locale === "es" ? updateI18n("es") : updateI18n("en");
@@ -75,9 +77,11 @@ export default function Page({ section, globalData, ...entryProps }) {
const Template = sectionMap[section] || PageTemplate;
return (
-
-
-
+
+
+
+
+
);
}
diff --git a/pages/api/authGoogle.js b/pages/api/authGoogle.js
new file mode 100644
index 00000000..8fb0671a
--- /dev/null
+++ b/pages/api/authGoogle.js
@@ -0,0 +1,26 @@
+import { OAuth2Client } from "google-auth-library";
+
+const GOOGLE_APP_ID = process.env.NEXT_PUBLIC_GOOGLE_APP_ID;
+const GOOGLE_APP_SECRET = process.env.GOOGLE_APP_SECRET;
+
+const oAuth2Client = new OAuth2Client(
+ GOOGLE_APP_ID,
+ GOOGLE_APP_SECRET,
+ "postmessage"
+);
+
+// exchanges Auth Code for Tokens
+async function getTokens(code) {
+ const { tokens } = await oAuth2Client.getToken(code);
+
+ return tokens;
+}
+
+export default async function handler(req, res) {
+ try {
+ const { id_token: idToken } = await getTokens(req.body.code);
+ res.status(200).json({ idToken });
+ } catch (err) {
+ res.status(500).json({ error: "failed to load data" });
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index af19b73a..4b61b71a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1982,6 +1982,11 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45"
integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
+"@react-oauth/google@^0.12.1":
+ version "0.12.1"
+ resolved "https://registry.yarnpkg.com/@react-oauth/google/-/google-0.12.1.tgz#b76432c3a525e9afe076f787d2ded003fcc1bee9"
+ integrity sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==
+
"@rubin-epo/epo-react-lib@^1.2.9":
version "1.2.9"
resolved "https://registry.yarnpkg.com/@rubin-epo/epo-react-lib/-/epo-react-lib-1.2.9.tgz#c67c071414f66d1a02381a84974f1b5692595cf5"
@@ -3249,15 +3254,6 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
-"@types/react@*":
- version "18.0.24"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.24.tgz#2f79ed5b27f08d05107aab45c17919754cc44c20"
- integrity sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
"@types/react@>=16":
version "18.0.37"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.37.tgz#7a784e2a8b8f83abb04dc6b9ed9c9b4c0aee9be7"
@@ -3595,6 +3591,13 @@ agent-base@6:
dependencies:
debug "4"
+agent-base@^7.0.2:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434"
+ integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==
+ dependencies:
+ debug "^4.3.4"
+
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@@ -4046,7 +4049,7 @@ balanced-match@^2.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
-base64-js@^1.3.1:
+base64-js@^1.3.0, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
@@ -4075,6 +4078,11 @@ big.js@^5.2.2:
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+bignumber.js@^9.0.0:
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
+ integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
+
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
@@ -4219,6 +4227,11 @@ buffer-crc32@~0.2.3:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
+buffer-equal-constant-time@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
+ integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
+
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
@@ -5164,6 +5177,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
+ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
+ integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
+ dependencies:
+ safe-buffer "^5.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -5861,7 +5881,7 @@ express@^4.16.3, express@^4.17.3:
utils-merge "1.0.1"
vary "~1.1.2"
-extend@^3.0.0, extend@~3.0.2:
+extend@^3.0.0, extend@^3.0.2, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -6282,6 +6302,24 @@ gauge@^3.0.0:
strip-ansi "^6.0.1"
wide-align "^1.1.2"
+gaxios@^6.0.0, gaxios@^6.1.1:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-6.3.0.tgz#5cd858de47c6560caaf0f99bb5d89c5bdfbe9034"
+ integrity sha512-p+ggrQw3fBwH2F5N/PAI4k/G/y1art5OxKpb2J2chwNNHM4hHuAOtivjPuirMF4KNKwTTUal/lPfL2+7h2mEcg==
+ dependencies:
+ extend "^3.0.2"
+ https-proxy-agent "^7.0.1"
+ is-stream "^2.0.0"
+ node-fetch "^2.6.9"
+
+gcp-metadata@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-6.1.0.tgz#9b0dd2b2445258e7597f2024332d20611cbd6b8c"
+ integrity sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==
+ dependencies:
+ gaxios "^6.0.0"
+ json-bigint "^1.0.0"
+
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -6512,6 +6550,18 @@ globjoin@^0.1.4:
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
+google-auth-library@^9.6.3:
+ version "9.6.3"
+ resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.6.3.tgz#add8935bc5b842a8e80f84fef2b5ed9febb41d48"
+ integrity sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==
+ dependencies:
+ base64-js "^1.3.0"
+ ecdsa-sig-formatter "^1.0.11"
+ gaxios "^6.1.1"
+ gcp-metadata "^6.1.0"
+ gtoken "^7.0.0"
+ jws "^4.0.0"
+
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@@ -6549,6 +6599,14 @@ graphql@^16.5.0:
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb"
integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==
+gtoken@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26"
+ integrity sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==
+ dependencies:
+ gaxios "^6.0.0"
+ jws "^4.0.0"
+
gunzip-maybe@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac"
@@ -6767,6 +6825,14 @@ https-proxy-agent@^5.0.1:
agent-base "6"
debug "4"
+https-proxy-agent@^7.0.1:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168"
+ integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==
+ dependencies:
+ agent-base "^7.0.2"
+ debug "4"
+
human-signals@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@@ -7414,6 +7480,13 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==
+json-bigint@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
+ integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
+ dependencies:
+ bignumber.js "^9.0.0"
+
json-parse-better-errors@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
@@ -7528,6 +7601,23 @@ jsx-ast-utils@^3.3.3:
object.assign "^4.1.4"
object.values "^1.1.6"
+jwa@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc"
+ integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==
+ dependencies:
+ buffer-equal-constant-time "1.0.1"
+ ecdsa-sig-formatter "1.0.11"
+ safe-buffer "^5.0.1"
+
+jws@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4"
+ integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==
+ dependencies:
+ jwa "^2.0.0"
+ safe-buffer "^5.0.1"
+
jwt-decode@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
@@ -8183,6 +8273,13 @@ node-fetch@^2.6.7:
dependencies:
whatwg-url "^5.0.0"
+node-fetch@^2.6.9:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
+ integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
+ dependencies:
+ whatwg-url "^5.0.0"
+
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -9151,7 +9248,7 @@ prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.6.0, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -9361,14 +9458,6 @@ react-fast-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
-react-google-login@^5.2.2:
- version "5.2.2"
- resolved "https://registry.yarnpkg.com/react-google-login/-/react-google-login-5.2.2.tgz#a20b46440c6c1610175ef75baf427118ff0e9859"
- integrity sha512-JUngfvaSMcOuV0lFff7+SzJ2qviuNMQdqlsDJkUM145xkGPVIfqWXq9Ui+2Dr6jdJWH5KYdynz9+4CzKjI5u6g==
- dependencies:
- "@types/react" "*"
- prop-types "^15.6.0"
-
react-hook-form@^7.33.1:
version "7.39.1"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.39.1.tgz#ded87d4b3f6692d1f9219515f78ca282b6e1ebf7"