Skip to content
Merged
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
16 changes: 14 additions & 2 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,19 @@ docker buildx build -t mono-ui:0.1-pre-release -f ./docker/mono-ui-dockerfile .
# .\init-volume.ps1 -baseDir "D:\" -configFile ".\config.toml"
```

[2] Start whole mono engine stack

[2] Start whole mono engine stack on local for testing
```bash
# create network
docker network create mono-network

# run postgres
docker run --rm -it -d --name mono-pg --network mono-network -v /tmp/data/mono/pg-data:/var/lib/postgresql/data -p 5432:5432 mono-pg:0.1-pre-release
docker run --rm -it -d --name mono-engine --network mono-network -v /tmp/data/mono/mono-data:/opt/mega -p 8000:8000 mono-engine:0.1-pre-release
docker run --rm -it -d --name mono-ui --network mono-network -e MEGA_INTERNAL_HOST=http://mono-engine:8000 -e MEGA_HOST=http://localhost:8000 -e MOON_HOST=http://localhost:3000 -p 3000:3000 mono-ui:0.1-pre-release
```

[3] Start whole mono engine stack on server with domain

```bash
# create network
Expand All @@ -40,5 +52,5 @@ docker network create mono-network
# run postgres
docker run --rm -it -d --name mono-pg --network mono-network -v /mnt/data/mono/pg-data:/var/lib/postgresql/data -p 5432:5432 mono-pg:0.1-pre-release
docker run --rm -it -d --name mono-engine --network mono-network -v /mnt/data/mono/mono-data:/opt/mega -p 8000:8000 -p 22:9000 mono-engine:0.1-pre-release
docker run --rm -it -d --name mono-ui --network mono-network -e MEGA_HOST=http://git.gitmono.com -e MOON_HOST=https://console.gitmono.com -p 3000:3000 mono-ui:0.1-pre-release
docker run --rm -it -d --name mono-ui --network mono-network -e MEGA_INTERNAL_HOST=http://mono-engine:8000 -e MEGA_HOST=http://git.gitmono.com -e MOON_HOST=https://console.gitmono.com -p 3000:3000 mono-ui:0.1-pre-release
```
2 changes: 1 addition & 1 deletion docker/mono-engine-dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ RUN if [ "$BUILD_TYPE" = "release" ]; then \
# final image
FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y libssl-dev
RUN apt-get update && apt-get install -y libssl-dev ca-certificates

ARG BUILD_TYPE=release

Expand Down
2 changes: 1 addition & 1 deletion docker/mono-ui-dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## exmaple: https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
FROM node:20-alpine AS base
FROM node:22-alpine AS base

# Install dependencies only when needed
FROM base AS deps
Expand Down
7 changes: 6 additions & 1 deletion docker/start-moon.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#!/bin/bash

# user must set the NEXT_PUBLIC_API_URL
# user must set the MEGA_HOST,MEGA_INTERNAL_HOST and MOON_HOST
if [ -z "$MEGA_HOST" ]; then
echo "MEGA_HOST is not set"
exit 1
fi

if [ -z "$MEGA_INTERNAL_HOST" ]; then
echo "MEGA_INTERNAL_HOST is not set"
exit 1
fi

if [ -z "$MOON_HOST" ]; then
echo "MOON_HOST is not set"
exit 1
Expand Down
12 changes: 6 additions & 6 deletions mono/src/api/oauth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::Arc;

use axum::async_trait;
use axum::response::Redirect;
use axum::routing::post;
use axum::{
extract::{Path, Query, State},
http::StatusCode,
Expand All @@ -15,6 +16,7 @@ use axum_extra::TypedHeader;
use tokio::sync::Mutex;
use uuid::Uuid;

use common::model::CommonResult;
use common::enums::SupportOauthType;
use common::errors::MegaError;
use github::GithubOauthService;
Expand Down Expand Up @@ -58,7 +60,7 @@ pub trait OauthHandler: Send + Sync {
pub fn routers() -> Router<OauthServiceState> {
Router::new()
.route("/:oauth_type/authorize", get(redirect_authorize))
.route("/:oauth_type/callback", get(oauth_callback))
.route("/:oauth_type/callback", post(oauth_callback))
.route("/:oauth_type/user", get(user))
}

Expand All @@ -85,7 +87,7 @@ async fn oauth_callback(
Path(oauth_type): Path<String>,
Query(query): Query<OauthCallbackParams>,
service_state: State<OauthServiceState>,
) -> Result<Redirect, (StatusCode, String)> {
) -> Result<Json<CommonResult<String>>, (StatusCode, String)> {
let oauth_type: SupportOauthType = match oauth_type.parse::<SupportOauthType>() {
Ok(value) => value,
Err(err) => return Err((StatusCode::BAD_REQUEST, err)),
Expand All @@ -96,17 +98,15 @@ async fn oauth_callback(

let redirect_uri = match sessions.get(&query.state) {
Some(uri) => uri.clone(),
None => return Err((StatusCode::BAD_REQUEST, "Invalid state".to_string())),
None => return Ok(Json(CommonResult::failed("Invalid state"))),
};
let access_token = service_state
.oauth_handler(oauth_type)
.access_token(query.clone(), &redirect_uri)
.await
.unwrap();
sessions.remove(&query.state);

let callback_url = format!("{}?access_token={}", redirect_uri, access_token);
Ok(Redirect::temporary(&callback_url))
Ok(Json(CommonResult::success(Some(access_token))))
}

async fn user(
Expand Down
5 changes: 3 additions & 2 deletions moon/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
# Variables not prefixed with NEXT_PUBLIC_ are only available on the server side.


# add MEGA_HOST and MOON_HOST to your enviroment for development
# MEGA_HOST default to http://localhost:8000, MOON_HOST default to http://localhost:3000
# add MEGA_HOST, MEGA_INTERNAL_HOST and MOON_HOST to your enviroment for development
# MEGA_HOST and MEGA_INTERNAL_HOST default to http://localhost:8000, MOON_HOST default to http://localhost:3000
MEGA_HOST=$MEGA_HOST
MEGA_INTERNAL_HOST=$MEGA_INTERNAL_HOST
CALLBACK_URL=$MOON_HOST/auth/github/callback

SECRET_KEY=$YOUR_SECRET_KEY #(not prefixed with NEXT_PUBLIC_ )
17 changes: 16 additions & 1 deletion moon/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
## Moon Module
## Moon Module

---

### Environment Variables

In the root directory of your project, three environment variables are required in the `.env` file:

- **MEGA_HOST**: Used for redirecting to public backend routes during the OAuth process.
- **MOON_HOST**: Provides the callback URL to the authentication provider.
- **MEGA_INTERNAL_HOST**: Utilized for internal API requests. Given that the application uses SSR and Next.js Route Handlers, this variable allows you to specify a domain name within the container network.

### Environment Handling

- **Development Mode**: Next.js automatically reads the environment variables from the `.env` file.
- **Production Mode**: Environment variables must be passed via Docker commands when deploying the application.
19 changes: 19 additions & 0 deletions moon/src/app/api/auth/github/callback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

// import { cookies } from "next/headers";
import { type NextRequest } from 'next/server'

export async function POST(request: NextRequest) {
const endpoint = process.env.MEGA_INTERNAL_HOST;
const searchParams = request.nextUrl.searchParams;
const code = searchParams.get("code");
const state = searchParams.get("state");
const res = await fetch(`${endpoint}/auth/github/callback?code=${code}&state=${state}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
const data = await res.json()

return Response.json({ data })
}
2 changes: 1 addition & 1 deletion moon/src/app/api/auth/github/user/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { cookies } from "next/headers";

export async function GET(request: Request) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const cookieStore = cookies();
const access_token = cookieStore.get('access_token');

Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/blob/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const dynamic = 'force-dynamic' // defaults to auto
export const revalidate = 0

export async function GET(request: NextRequest) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const searchParams = request.nextUrl.searchParams
const path = searchParams.get('path')

Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/mr/[id]/detail/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic' // defaults to auto
export const revalidate = 0

export async function GET(request: Request, { params }: { params: { id: string } }) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const res = await fetch(`${endpoint}/api/v1/mr/${params.id}/detail`, {
})
const data = await res.json()
Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/mr/[id]/files/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export const dynamic = 'force-dynamic' // defaults to auto

export async function GET(request: Request, { params }: { params: { id: string } }) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const res = await fetch(`${endpoint}/api/v1/mr/${params.id}/files`, {
})
const data = await res.json()
Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/mr/[id]/merge/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic' // defaults to auto


export async function POST(request: Request, { params }: { params: { id: string } }) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const res = await fetch(`${endpoint}/api/v1/mr/${params.id}/merge`, {
method: 'POST',
})
Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/mr/list/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const revalidate = 0
import { type NextRequest } from 'next/server'

export async function GET(request: NextRequest) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const searchParams = request.nextUrl.searchParams
const status = searchParams.get('status')
const res = await fetch(`${endpoint}/api/v1/mr/list?status=${status}`, {
Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/tree/commit-info/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const revalidate = 0


export async function GET(request: NextRequest) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;
const searchParams = request.nextUrl.searchParams
const path = searchParams.get('path')

Expand Down
2 changes: 1 addition & 1 deletion moon/src/app/api/tree/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export const revalidate = 0
export const dynamic = 'force-dynamic' // defaults to auto

export async function GET(request: NextRequest) {
const endpoint = process.env.MEGA_HOST;
const endpoint = process.env.MEGA_INTERNAL_HOST;

const searchParams = request.nextUrl.searchParams
const path = searchParams.get('path')
Expand Down
58 changes: 29 additions & 29 deletions moon/src/app/auth/github/callback/page.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
'use client'

import { handleLogin } from '@/app/actions';
import { useEffect, useState } from 'react';

interface enviroment {
mega_host: string;
callback_url: string;
}
import { useCallback, useEffect } from 'react';
import { message } from "antd";

export default function AuthPage({ searchParams }) {
const [data, setData] = useState<enviroment | null>(null);
const [loading, setLoading] = useState(true);
const [messageApi, contextHolder] = message.useMessage();


const error = useCallback((err_msg) => {
messageApi.open({
type: 'error',
content: err_msg,
});
}, [messageApi]);
const code = searchParams.code;
const state = searchParams.state;

useEffect(() => {
async function fetchData() {
try {
const res = await fetch(`/api/env`);
const res = await fetch(`/api/auth/github/callback?code=${code}&state=${state}`, {
method: 'POST',
});
if (!res.ok) {
throw new Error('Failed to fetch data');
}
const result = await res.json();
setData(result);
let data = result.data;
if (data.req_result) {
handleLogin(data.data)
} else {
error(data.err_message)
}
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
}

fetchData();
}, []);

if (loading) return <div>Loading...</div>;
if (!data) return <div>Env Route Error</div>;

const access_token = searchParams.access_token || "";
const code = searchParams.code || "";
const state = searchParams.state || "";

if (code && state) {
const targetUrl = `${data.mega_host}/auth/github/callback?code=${code}&state=${state}`;
window.location.href = targetUrl;
} else if (access_token) {
handleLogin(access_token)
}
if (code && state) {
fetchData();
}
}, [code, state, error]);
return <>
{contextHolder}
</>
}