Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: poc for auto login on the consent screen #3348

Closed
Closed
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
66 changes: 48 additions & 18 deletions apps/consent/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import { LoginType, SubmitValue } from "../index.types";
import { LoginEmailResponse } from "./email-login.types";
import { headers } from "next/headers";
import { cookies } from "next/headers";
import { env } from "@/env";
import axios from "axios";

// this page is for login via email
interface LoginProps {
login_challenge: string;
login_challenge: string
}

async function submitForm(
Expand All @@ -46,7 +48,7 @@ async function submitForm(
typeof login_challenge !== "string" ||
typeof submitValue !== "string"
) {
throw new Error("Invalid Value");
throw new Error("Invalid Value")
}

if (submitValue === SubmitValue.denyAccess) {
Expand All @@ -69,19 +71,19 @@ async function submitForm(
}

if (!email || typeof email !== "string") {
console.error("Invalid Values for email");
throw new Error("Invalid Email Value");
console.error("Invalid Values for email")
throw new Error("Invalid Email Value")
}

let emailCodeRequest;
let emailCodeRequest
try {
emailCodeRequest = await authApi.requestEmailCode(email, customHeaders);
} catch (err) {
console.error("error while calling emailRequest Code", err);
console.error("error while calling emailRequest Code", err)
}

if (!emailCodeRequest) {
throw new Error("Request failed to get email code");
throw new Error("Request failed to get email code")
}

// TODO: manage error on ip rate limit
Expand All @@ -95,21 +97,21 @@ async function submitForm(
value: email,
remember,
}),
{ secure: true }
);
{ secure: true, sameSite: "lax" },
)

let params = new URLSearchParams({
login_challenge,
});
redirect(`/login/verification?${params}`);
})
redirect(`/login/verification?${params}`)
}

const Login = async ({ searchParams }: { searchParams: LoginProps }) => {
const { login_challenge } = searchParams;
let body: OAuth2LoginRequest;
const { login_challenge } = searchParams
let body: OAuth2LoginRequest

if (!login_challenge) {
throw new Error("Invalid Request");
throw new Error("Invalid Request")
}

const { data } = await hydraClient.getOAuth2LoginRequest(
Expand All @@ -123,7 +125,7 @@ const Login = async ({ searchParams }: { searchParams: LoginProps }) => {
}
);

body = data;
body = data
if (body.skip) {
let response: OAuth2RedirectTo;
const { data } = await hydraClient.acceptOAuth2LoginRequest(
Expand All @@ -143,6 +145,34 @@ const Login = async ({ searchParams }: { searchParams: LoginProps }) => {
redirect(String(response.redirect_to));
}

const useSecureCookies = env.DASHBOARD_URL.startsWith("https://")
const cookiePrefix = useSecureCookies ? "__Secure-" : ""
const cookieNameSession = `${cookiePrefix}next-auth.session-token`
const cookie = cookies().get(cookieNameSession)

if (cookie) {
const response = await axios(`${env.DASHBOARD_URL}/api/auth/session`, {
method: "GET",
headers: {
Cookie: cookies().toString(),
},
})
const userId = response?.data?.userData?.data?.me?.id
console.log(userId)

if (userId) {
const response2 = await hydraClient.acceptOAuth2LoginRequest({
loginChallenge: login_challenge,
acceptOAuth2LoginRequest: {
subject: userId,
remember: false,
acr: "2", // FIXME
},
})
redirect(response2.data.redirect_to)
}
}

return (
<MainContent>
<Card>
Expand Down Expand Up @@ -210,6 +240,6 @@ const Login = async ({ searchParams }: { searchParams: LoginProps }) => {
</FormComponent>
</Card>
</MainContent>
);
};
export default Login;
)
}
export default Login
2 changes: 1 addition & 1 deletion apps/consent/app/login/phone/server-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export const sendPhoneCode = async (
value: phone,
remember: remember,
}),
{ secure: true }
{ secure: true, sameSite: "lax" }
);

let params = new URLSearchParams({
Expand Down
32 changes: 17 additions & 15 deletions apps/consent/env.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
import { createEnv } from "@t3-oss/env-nextjs"
import { z } from "zod"

export const env = createEnv({
server: {
HYDRA_ADMIN_URL: z.string().default("http://localhost:4445"),
CORE_AUTH_URL: z.string().default("http://localhost:4002/auth"),
},
shared: {
GRAPHQL_ENDPOINT: z.string().default("http://localhost:4002/graphql"),
},
runtimeEnv: {
CORE_AUTH_URL: process.env.CORE_AUTH_URL,
HYDRA_ADMIN_URL: process.env.HYDRA_ADMIN_URL,
GRAPHQL_ENDPOINT: process.env.GRAPHQL_ENDPOINT,
},
});
server: {
HYDRA_ADMIN_URL: z.string().default("http://localhost:4445"),
CORE_AUTH_URL: z.string().default("http://localhost:4002/auth"),
DASHBOARD_URL: z.string().default("http://localhost:3001"),
},
shared: {
GRAPHQL_ENDPOINT: z.string().default("http://localhost:4002/graphql"),
},
runtimeEnv: {
CORE_AUTH_URL: process.env.CORE_AUTH_URL,
HYDRA_ADMIN_URL: process.env.HYDRA_ADMIN_URL,
GRAPHQL_ENDPOINT: process.env.GRAPHQL_ENDPOINT,
DASHBOARD_URL: process.env.DASHBOARD_URL,
},
})
20 changes: 19 additions & 1 deletion apps/dashboard/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ declare module "next-auth" {
}
}

const type = "oauth" as const
const useSecureCookies = process.env.NEXTAUTH_URL?.startsWith("https://")
const cookiePrefix = useSecureCookies ? "__Secure-" : ""
const heightHours = 8 * 60 * 60 * 1000
const expires = new Date(Date.now() + heightHours)

const type = "oauth" as const;
export const authOptions: AuthOptions = {
providers: [
{
Expand Down Expand Up @@ -68,6 +73,19 @@ export const authOptions: AuthOptions = {
return session
},
},
cookies: {
sessionToken: {
name: `${cookiePrefix}next-auth.session-token`,
options: {
httpOnly: true,
sameSite: "lax",
path: "/",
// domain: ".localhost", // FIXME: use env variable
secure: useSecureCookies,
expires,
},
},
},
}

const handler = NextAuth(authOptions)
Expand Down