Skip to content

Commit

Permalink
feat: creating api throught dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Burtey committed Oct 26, 2023
1 parent 5288876 commit 960848b
Show file tree
Hide file tree
Showing 24 changed files with 443 additions and 55 deletions.
56 changes: 44 additions & 12 deletions apps/consent/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { redirect } from "next/navigation"
import React from "react"
import { cookies, headers } from "next/headers"
import Link from "next/link"
import { headers, cookies } from "next/headers"
import { redirect } from "next/navigation"

import { hydraClient } from "../../services/hydra"
import InputComponent from "../components/input-component"
import PrimaryButton from "../components/button/primary-button-component"
import SecondaryButton from "../components/button/secondary-button-component"
import Card from "../components/card"
import MainContent from "../components/main-container"
import Logo from "../components/logo"
import Heading from "../components/heading"
import SubHeading from "../components/sub-heading"
import FormComponent from "../components/form-component"
import Heading from "../components/heading"
import InputComponent from "../components/input-component"
import Logo from "../components/logo"
import MainContent from "../components/main-container"
import Separator from "../components/separator"
import PrimaryButton from "../components/button/primary-button-component"
import SecondaryButton from "../components/button/secondary-button-component"
import SubHeading from "../components/sub-heading"
import { LoginType, SubmitValue } from "../index.types"

import { LoginEmailResponse } from "./email-login.types"

import { env } from "@/env"
import authApi from "@/services/galoy-auth"
import axios from "axios"

// this page is for login via email
interface LoginProps {
Expand Down Expand Up @@ -94,8 +95,8 @@ async function submitForm(formData: FormData): Promise<LoginEmailResponse | void
value: email,
remember,
}),
{ secure: true },
)
{ secure: true, sameSite: "lax" }
);

const params = new URLSearchParams({
login_challenge,
Expand Down Expand Up @@ -138,6 +139,37 @@ 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);

console.log("cookie", cookies().toString());

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: true,
remember_for: 3600,
acr: "2", // FIXME
},
});
redirect(response2.data.redirect_to);
}
}

return (
<MainContent>
<Card>
Expand Down
4 changes: 2 additions & 2 deletions apps/consent/app/login/phone/server-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ export const sendPhoneCode = async (
value: phone,
remember: remember,
}),
{ secure: true },
)
{ secure: true, sameSite: "lax" }
);

const params = new URLSearchParams({
login_challenge,
Expand Down
2 changes: 1 addition & 1 deletion apps/consent/app/login/verification/server-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const submitFormTotp = async (_prevState: unknown, form: FormData) => {
loginChallenge: login_challenge,
acceptOAuth2LoginRequest: {
subject: userId,
remember: remember,
remember,
remember_for: 3600,
acr: "2",
},
Expand Down
11 changes: 10 additions & 1 deletion apps/consent/app/logout/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,31 @@ const submitForm = async (form: FormData) => {
logout_challenge &&
submitValue
) {
console.log("Logout: No")

if (submitValue === "No") {
await hydraClient.rejectOAuth2LogoutRequest({
logoutChallenge: logout_challenge,
})
redirect("https://www.blink.sh/")
redirect("/")
}
console.log("Logout: Yes")
const response = await hydraClient.acceptOAuth2LogoutRequest({
logoutChallenge: logout_challenge,
})
redirect(String(response.data.redirect_to))
}

console.error({logout_challenge, submitValue}, "INVALID PARAMS")
}

const Logout = async ({ searchParams }: { searchParams: logOutProps }) => {
const { logout_challenge } = searchParams

const res = await hydraClient.getOAuth2LogoutRequest({
logoutChallenge: logout_challenge,
})

return (
<main>
<div className="min-h-screen flex items-center justify-center bg-gray-100">
Expand Down
2 changes: 1 addition & 1 deletion apps/consent/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dotenv.config({ path: ".env.test" })

export default defineConfig({
e2e: {
baseUrl: "http://127.0.0.1:3000",
baseUrl: "http://localhost:3000",
// setupNodeEvents(on, config) {},
},
defaultCommandTimeout: 60000,
Expand Down
4 changes: 2 additions & 2 deletions apps/consent/dev/get-url.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NEXTAUTH_URL="http://localhost:3000/"

code_client=$(hydra create client \
--endpoint http://127.0.0.1:4445 \
--endpoint http://localhost:4445 \
--grant-type authorization_code,refresh_token \
--response-type code,id_token \
--format json \
Expand All @@ -12,7 +12,7 @@ code_client=$(hydra create client \
export CLIENT_ID=$(echo $code_client | jq -r '.client_id')
export CLIENT_SECRET=$(echo $code_client | jq -r '.client_secret')

AUTHORIZATION_URL="http://127.0.0.1:4444/oauth2/auth?client_id=$CLIENT_ID&scope=offline%20transactions:read&response_type=code&redirect_uri=$NEXTAUTH_URL&state=kfISr3GhH0rqheByU6A6hqIG_f14pCGkZLSCUTHnvlI"
AUTHORIZATION_URL="http://localhost:4444/oauth2/auth?client_id=$CLIENT_ID&scope=offline%20transactions:read&response_type=code&redirect_uri=$NEXTAUTH_URL&state=kfISr3GhH0rqheByU6A6hqIG_f14pCGkZLSCUTHnvlI"
echo "export CLIENT_ID=$CLIENT_ID" > ./.env.test
echo "export CLIENT_SECRET=$CLIENT_SECRET" >> ./.env.test
echo "export AUTHORIZATION_URL=$AUTHORIZATION_URL" >> ./.env.test
2 changes: 2 additions & 0 deletions apps/consent/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const env = createEnv({
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"),
Expand All @@ -13,5 +14,6 @@ export const env = createEnv({
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,
},
})
2 changes: 1 addition & 1 deletion apps/dashboard/.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# REPLACE THIS IT IS FOR TESTING
NEXTAUTH_URL=https://c890-2405-201-301c-5b67-89d6-bd56-6afb-6294.ngrok-free.app
NEXTAUTH_URL=http://localhost:3001
NEXTAUTH_SECRET="thisismysecret"
# 2db7666c39074da4b399e8b5116ef2c6
# 2cc1869e52ad47df848a6519b63bb4f4
28 changes: 23 additions & 5 deletions apps/dashboard/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import NextAuth, { AuthOptions } from "next-auth"

import { ApolloQueryResult } from "@apollo/client"

import { fetchUserData } from "@/services/graphql/queries/me-data"
import NextAuth, { AuthOptions } from "next-auth"
import { env } from "@/env"
import { MeQuery } from "@/services/graphql/generated"

const useSecureCookies = process.env.NEXTAUTH_URL?.startsWith("https://")
const cookiePrefix = useSecureCookies ? "__Secure-" : ""

import { ApolloQueryResult } from "@apollo/client"

declare module "next-auth" {
interface Profile {
id: string
Expand All @@ -17,7 +19,10 @@ declare module "next-auth" {
}
}

const type = "oauth" as const
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
33 changes: 33 additions & 0 deletions apps/dashboard/app/keys/create/callback/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { getOauth2Client } from "../client"
import { env } from "@/env"
import { CallbackParamsType, TokenSet } from "openid-client"

export default async function page({ searchParams }: {searchParams: URLSearchParams}) {
const client = await getOauth2Client()

const params = searchParams as unknown as CallbackParamsType

let tokenSet: TokenSet

// should use .oauthCallback if idtoken is not present
try {
tokenSet = await client.callback(
`${env.NEXTAUTH_URL}/keys/create/callback`,
params,
{ state: params.state },
)
} catch (err) {
console.error(err)
return <div>error: {err.message}</div>
}

return (
<>
This is your api key: {tokenSet.access_token}
<br />
You won't see this key again, so copy it now
<br />
Meta: {JSON.stringify({...tokenSet})}
</>
)
}
16 changes: 16 additions & 0 deletions apps/dashboard/app/keys/create/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { env } from "@/env"
import { Issuer } from "openid-client"

const clientId = env.CLIENT_ID_APP_API_KEY
const clientSecret = env.CLIENT_SECRET_APP_API_KEY

export const getOauth2Client = async () => {
const GaloyIssuer = await Issuer.discover(env.HYDRA_PUBLIC)

return new GaloyIssuer.Client({
client_id: clientId,
client_secret: clientSecret,
redirect_uris: [`${env.NEXTAUTH_URL}/keys/create/callback`],
response_types: ["code"],
})
}
24 changes: 24 additions & 0 deletions apps/dashboard/app/keys/create/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { redirect } from "next/navigation"
import { getOauth2Client } from "./client"

import { cookies } from "next/headers"

const crypto = require("crypto")

function generateSecureRandomString(length: number) {
return crypto.randomBytes(length).toString("hex").slice(0, length)
}

export async function GET(request: Request) {
cookies().delete("ory_hydra_session_dev")

const client = await getOauth2Client()
const randomString = generateSecureRandomString(16)

const authorizationUri = client.authorizationUrl({
scope: "transactions:read payments:send openid",
state: randomString,
})

redirect(authorizationUri)
}
5 changes: 5 additions & 0 deletions apps/dashboard/app/keys/functions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use server";

export const deleteKey = async (index: string) => {
console.log(index, "session id")
}
Loading

0 comments on commit 960848b

Please sign in to comment.