Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/pr-review-client-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ jobs:
echo "URL=$URL" >> $GITHUB_ENV

aws lambda update-function-configuration \
--function-name $FUNCTION_NAME-$PR_NUMBER > /dev/null 2>&1
--function-name $FUNCTION_NAME-$PR_NUMBER \
--environment "Variables={NEXTAUTH_URL=$URL}" > /dev/null 2>&1

aws logs create-log-group --log-group-name /aws/lambda/$FUNCTION_NAME-$PR_NUMBER > /dev/null 2>&1
aws logs put-retention-policy --log-group-name /aws/lambda/$FUNCTION_NAME-$PR_NUMBER --retention-in-days 14 > /dev/null 2>&1
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile.pr
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ ENV AWS_LWA_ENABLE_COMPRESSION=true
ENV HOSTNAME=localhost
ENV PORT=3000

ENV ZITADEL_CLIENT_ID=343363438019420754
ENV ZITADEL_URL=https://auth.forms-staging.cdssandbox.xyz

# Use the LAMBDA_ENV environment variable to determine if the app is running in a Lambda environment
# Enables memory caching for the prerendering of pages
ENV LAMBDA_ENV=1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";
import { signIn } from "next-auth/react";
import { useSession } from "next-auth/react";

export const Login = ({ language = "en" }) => {
const { data, status } = useSession();

if (status === "loading") {
return;
}

if (status === "authenticated") {
return <div>{`Hello ${data.user?.name}`}</div>;
}
return (
<form
action={async () => {
signIn("gcForms", { redirectTo: `/${language}/auth/policy` });
}}
>
<button
className="rounded-xl border-3 border-gcds-gray-500 p-3 text-blue-900 hover:border-gcds-blue-800 hover:bg-gcds-blue-800 hover:text-white-default active:border-black"
type="submit"
>
Sign in with Zitadel
</button>
</form>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { serverTranslation } from "@i18n";
import { Metadata } from "next";
import { Login } from "./Login";
import { authCheckAndThrow } from "@lib/actions";
import { redirect } from "next/navigation";

export async function generateMetadata(props: {
params: Promise<{ locale: string }>;
}): Promise<Metadata> {
const params = await props.params;

const { locale } = params;

const { t } = await serverTranslation(["login"], { lang: locale });
return {
title: t("title"),
};
}

export default async function Page(props: { params: Promise<{ locale: string }> }) {
const params = await props.params;

const { locale } = params;

const { session } = await authCheckAndThrow().catch(() => ({ session: null }));
if (session) {
redirect(`/${locale}/forms`);
}

return (
<div id="auth-panel">
<Login />
</div>
);
}
19 changes: 17 additions & 2 deletions app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import { GET as NextGET, POST as NextPOST } from "@lib/auth";
import { NextRequest, NextResponse } from "next/server";
import { logMessage } from "@root/lib/logger";

// Only allow methods and paths that the application uses for Authjs

const GET = async (req: NextRequest) => {
if (["/api/auth/session", "/api/auth/csrf"].includes(req.nextUrl.pathname)) {
if (
[
"/api/auth/error",
"/api/auth/session",
"/api/auth/csrf",
"/api/auth/providers",
"/api/auth/callback/gcForms",
].includes(req.nextUrl.pathname)
) {
return NextGET(req);
}
logMessage.error(`Attempted GET URL: ${req.nextUrl.pathname}`);
return NextResponse.json({ error: "Bad Request" }, { status: 400 });
};

const POST = async (req: NextRequest) => {
if (["/api/auth/session", "/api/auth/signout"].includes(req.nextUrl.pathname)) {
if (
["/api/auth/session", "/api/auth/signout", "/api/auth/signin/gcForms"].includes(
req.nextUrl.pathname
)
) {
return NextPOST(req);
}
logMessage.error(`Attempted POST URL: ${req.nextUrl.pathname}`);
return NextResponse.json({ error: "Bad Request" }, { status: 400 });
};

Expand Down
1 change: 0 additions & 1 deletion components/clientComponents/globals/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Markdown from "markdown-to-jsx";
import { useFeatureFlags } from "@lib/hooks/useFeatureFlags";
import { FeatureFlags } from "@lib/cache/types";
import { SkipLink } from "../SkipLink";

type HeaderParams = {
context?: "admin" | "formBuilder" | "default";
className?: string;
Expand Down
39 changes: 20 additions & 19 deletions lib/auth/nextAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { activeStatusCheck, activeStatusUpdate } from "@lib/cache/userActiveStat
import { JWT } from "next-auth/jwt";
import { cache } from "react";
import { headers } from "next/headers";
// import ZitadelProvider from "next-auth/providers/zitadel";

/**
* Checks the active status of a user using a cache strategy
Expand Down Expand Up @@ -50,23 +49,21 @@ const {
signOut,
} = NextAuth({
providers: [
// Keep this commented out for now, as we are not using Zitadel for authentication within the app
// ZitadelProvider({
// issuer: process.env.ZITADEL_ISSUER,
// clientId: process.env.ZITADEL_CLIENT_ID,
// checks: ["pkce"],
// client: {
// token_endpoint_auth_method: "none",
// },
// allowDangerousEmailAccountLinking: true,
// async profile(profile) {
// return {
// id: profile.sub,
// name: profile.name,
// email: profile.email,
// };
// },
// }),
{
id: "gcForms", // signIn("my-provider") and will be part of the callback URL
name: "GC Forms", // optional, used on the default login page as the button text.
type: "oidc",
issuer: process.env.ZITADEL_URL,
clientId: process.env.ZITADEL_CLIENT_ID,
checks: ["pkce", "state"],
client: { token_endpoint_auth_method: "none" },
allowDangerousEmailAccountLinking: true,
authorization: {
params: {
scope: "openid email profile",
},
},
},
CredentialsProvider({
id: "mfa",
name: "MultiFactorAuth",
Expand Down Expand Up @@ -137,7 +134,6 @@ const {
},
// Elastic Load Balancer safely sets the host header and ignores the incoming request headers
trustHost: true,
debug: process.env.NODE_ENV !== "production",
logger: {
error(error) {
if (!(error instanceof CredentialsSignin)) {
Expand All @@ -148,6 +144,11 @@ const {
warn(code) {
logMessage.warn(`NextAuth warning - Code: ${code}`);
},
debug(code, ...message) {
// TODO.. switch back to debug
logMessage.info(code);
logMessage.info(message);
},
},

adapter: PrismaAdapter(prisma),
Expand Down
2 changes: 1 addition & 1 deletion scripts/pr-review-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ load_non_existing_envs() {
key="${line%%=*}"
value="${line#*=}"

if [ -z "$(var_expand "$key")" ] && [ $key != "NEXTAUTH_URL" ]; then # Check if environment variable doesn't exist
if [ -z "$(var_expand "$key")" ] && [ $key != "NEXTAUTH_URL" ] && [ $key != "ZITADEL_URL" ]; then # Check if environment variable doesn't exist
export "${key}=${value}"
fi
done < $TMP_ENV_FILE
Expand Down
Loading