mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
Merge pull request #68 from learnhouse/feat/better-error-handling-and-private-routes-protection
Better Error handling & Routes protection
This commit is contained in:
commit
f519c5f8bf
35 changed files with 191 additions and 176 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
|
@ -19,6 +20,7 @@ class DatabaseConfig(BaseModel):
|
||||||
user: str
|
user: str
|
||||||
password: str
|
password: str
|
||||||
database_name: str
|
database_name: str
|
||||||
|
mongodb_connection_string: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
class LearnHouseConfig(BaseModel):
|
class LearnHouseConfig(BaseModel):
|
||||||
|
|
@ -54,6 +56,8 @@ def get_learnhouse_config() -> LearnHouseConfig:
|
||||||
env_user = os.environ.get('LEARNHOUSE_DB_USER')
|
env_user = os.environ.get('LEARNHOUSE_DB_USER')
|
||||||
env_password = os.environ.get('LEARNHOUSE_DB_PASSWORD')
|
env_password = os.environ.get('LEARNHOUSE_DB_PASSWORD')
|
||||||
env_database_name = os.environ.get('LEARNHOUSE_DB_NAME')
|
env_database_name = os.environ.get('LEARNHOUSE_DB_NAME')
|
||||||
|
env_mongodb_connection_string = os.environ.get(
|
||||||
|
'LEARNHOUSE_MONGODB_CONNECTION_STRING')
|
||||||
|
|
||||||
# Fill in values with YAML file if they are not provided
|
# Fill in values with YAML file if they are not provided
|
||||||
site_name = env_site_name or yaml_config.get('site_name')
|
site_name = env_site_name or yaml_config.get('site_name')
|
||||||
|
|
@ -80,6 +84,8 @@ def get_learnhouse_config() -> LearnHouseConfig:
|
||||||
'database_config', {}).get('password')
|
'database_config', {}).get('password')
|
||||||
database_name = env_database_name or yaml_config.get(
|
database_name = env_database_name or yaml_config.get(
|
||||||
'database_config', {}).get('database_name')
|
'database_config', {}).get('database_name')
|
||||||
|
mongodb_connection_string = env_mongodb_connection_string or yaml_config.get(
|
||||||
|
'database_config', {}).get('mongodb_connection_string')
|
||||||
|
|
||||||
# Create HostingConfig and DatabaseConfig objects
|
# Create HostingConfig and DatabaseConfig objects
|
||||||
hosting_config = HostingConfig(
|
hosting_config = HostingConfig(
|
||||||
|
|
@ -96,7 +102,8 @@ def get_learnhouse_config() -> LearnHouseConfig:
|
||||||
port=int(db_port),
|
port=int(db_port),
|
||||||
user=user,
|
user=user,
|
||||||
password=password,
|
password=password,
|
||||||
database_name=database_name
|
database_name=database_name,
|
||||||
|
mongodb_connection_string=mongodb_connection_string
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create LearnHouseConfig object
|
# Create LearnHouseConfig object
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,4 @@ database_config:
|
||||||
user: myuser
|
user: myuser
|
||||||
password: mypassword
|
password: mypassword
|
||||||
database_name: mydatabase
|
database_name: mydatabase
|
||||||
|
mongodb_connection_string: mongodb://learnhouse:learnhouse@mongo:27017/
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import AuthProvider from "@components/Security/AuthProvider";
|
||||||
import EditorWrapper from "@components/Editor/EditorWrapper";
|
import EditorWrapper from "@components/Editor/EditorWrapper";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
|
|
||||||
function EditActivity(params: any) {
|
function EditActivity(params: any) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { Title } from "@components/UI/Elements/Styles/Title";
|
||||||
import { createCollection } from "@services/courses/collections";
|
import { createCollection } from "@services/courses/collections";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
||||||
|
|
||||||
function NewCollection(params : any) {
|
function NewCollection(params : any) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import styled from "styled-components";
|
||||||
import { Title } from "@components/UI/Elements/Styles/Title";
|
import { Title } from "@components/UI/Elements/Styles/Title";
|
||||||
import { deleteCollection } from "@services/courses/collections";
|
import { deleteCollection } from "@services/courses/collections";
|
||||||
import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
|
import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
|
|
||||||
function Collections(params: any) {
|
function Collections(params: any) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { getCourse } from "@services/courses/courses";
|
||||||
import VideoActivity from "@components/Pages/Activities/Video/Video";
|
import VideoActivity from "@components/Pages/Activities/Video/Video";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { Check } from "lucide-react";
|
import { Check } from "lucide-react";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import { markActivityAsComplete } from "@services/courses/activity";
|
import { markActivityAsComplete } from "@services/courses/activity";
|
||||||
|
|
||||||
function ActivityPage(params: any) {
|
function ActivityPage(params: any) {
|
||||||
|
|
@ -19,7 +19,7 @@ function ActivityPage(params: any) {
|
||||||
const orgslug = params.params.orgslug;
|
const orgslug = params.params.orgslug;
|
||||||
|
|
||||||
const { data: course, error: error_course } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, swrFetcher);
|
const { data: course, error: error_course } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, swrFetcher);
|
||||||
const { data: activity, error: error_activity } = useSWR(`${getAPIUrl()}trail/org_slug/${orgslug}/trail`, swrFetcher);
|
const { data: activity, error: error_activity } = useSWR(`${getAPIUrl()}activities/activity_${activityid}`, swrFetcher);
|
||||||
|
|
||||||
|
|
||||||
async function markActivityAsCompleteFront() {
|
async function markActivityAsCompleteFront() {
|
||||||
|
|
@ -31,7 +31,7 @@ function ActivityPage(params: any) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{error_course && <p>Failed to load</p>}
|
{error_course && <p>Failed to load</p>}
|
||||||
{!course || !activity ? (
|
{!course && !activity ? (
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
) : (
|
) : (
|
||||||
<ActivityLayout>
|
<ActivityLayout>
|
||||||
|
|
@ -95,9 +95,8 @@ function ActivityPage(params: any) {
|
||||||
)}
|
)}
|
||||||
</ActivityMarkerWrapper>
|
</ActivityMarkerWrapper>
|
||||||
</CourseContent>
|
</CourseContent>
|
||||||
) : (
|
) : (<div></div>)}
|
||||||
<div>Loading...</div>
|
{error_activity && <p>Failed to load {error_activity.message}</p>}
|
||||||
)}
|
|
||||||
</ActivityLayout>
|
</ActivityLayout>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import { createActivity, createFileActivity } from "@services/courses/activities
|
||||||
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
import { getOrganizationContextInfo } from "@services/organizations/orgs";
|
||||||
import Modal from "@components/UI/Modal/Modal";
|
import Modal from "@components/UI/Modal/Modal";
|
||||||
import AuthProvider from "@components/Security/AuthProvider";
|
import AuthProvider from "@components/Security/AuthProvider";
|
||||||
|
import { denyAccessToUser } from "@services/utils/react/middlewares/views";
|
||||||
|
|
||||||
function CourseEdit(params: any) {
|
function CourseEdit(params: any) {
|
||||||
|
|
||||||
|
|
@ -38,9 +39,7 @@ function CourseEdit(params: any) {
|
||||||
const courseChapters = await getCourseChaptersMetadata(courseid);
|
const courseChapters = await getCourseChaptersMetadata(courseid);
|
||||||
setData(courseChapters);
|
setData(courseChapters);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.status === 401) {
|
denyAccessToUser(error, router)
|
||||||
router.push("/login");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,17 @@ import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
|
import { getAPIUrl, getBackendUrl, getUriWithOrg } from "@services/config/config";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
const CourseIdPage = (params: any) => {
|
const CourseIdPage = (params: any) => {
|
||||||
const courseid = params.params.courseid;
|
const courseid = params.params.courseid;
|
||||||
const orgslug = params.params.orgslug;
|
const orgslug = params.params.orgslug;
|
||||||
const { data: course, error: error } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`, swrFetcher);
|
const router = useRouter();
|
||||||
|
|
||||||
|
const { data: course, error: error } = useSWR(`${getAPIUrl()}courses/meta/course_${courseid}`,
|
||||||
|
(url: string, body: any) => swrFetcher(url, body, router)
|
||||||
|
);
|
||||||
|
|
||||||
async function startCourseUI() {
|
async function startCourseUI() {
|
||||||
// Create activity
|
// Create activity
|
||||||
|
|
@ -42,7 +47,7 @@ const CourseIdPage = (params: any) => {
|
||||||
<p>Course</p>
|
<p>Course</p>
|
||||||
<h1>
|
<h1>
|
||||||
{course.course.name}{" "}
|
{course.course.name}{" "}
|
||||||
<Link href={getUriWithOrg(orgslug,"") +`/course/${courseid}/edit`} rel="noopener noreferrer">
|
<Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}/edit`} rel="noopener noreferrer">
|
||||||
<Pencil2Icon />
|
<Pencil2Icon />
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
@ -53,7 +58,7 @@ const CourseIdPage = (params: any) => {
|
||||||
{chapter.activities.map((activity: any) => {
|
{chapter.activities.map((activity: any) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Link href={getUriWithOrg(orgslug,"") +`/course/${courseid}/activity/${activity.id.replace("activity_", "")}`}>
|
<Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`}>
|
||||||
<ChapterIndicator />
|
<ChapterIndicator />
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
</>
|
</>
|
||||||
|
|
@ -94,7 +99,7 @@ const CourseIdPage = (params: any) => {
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
Activity {activity.name}
|
Activity {activity.name}
|
||||||
<Link href={getUriWithOrg(orgslug,"") +`/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
|
<Link href={getUriWithOrg(orgslug, "") + `/course/${courseid}/activity/${activity.id.replace("activity_", "")}`} rel="noopener noreferrer">
|
||||||
<EyeOpenIcon />
|
<EyeOpenIcon />
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { Title } from "@components/UI/Elements/Styles/Title";
|
||||||
import { getAPIUrl, getBackendUrl, getSelfHostedOption, getUriWithOrg } from "@services/config/config";
|
import { getAPIUrl, getBackendUrl, getSelfHostedOption, getUriWithOrg } from "@services/config/config";
|
||||||
import { deleteCourseFromBackend } from "@services/courses/courses";
|
import { deleteCourseFromBackend } from "@services/courses/courses";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import { Edit2, Trash } from "lucide-react";
|
import { Edit2, Trash } from "lucide-react";
|
||||||
|
|
||||||
const CoursesIndexPage = (params: any) => {
|
const CoursesIndexPage = (params: any) => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { getAPIUrl, getBackendUrl } from "@services/config/config";
|
import { getAPIUrl, getBackendUrl } from "@services/config/config";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { styled } from "styled-components";
|
import { styled } from "styled-components";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import { getAPIUrl } from '@services/config/config';
|
import { getAPIUrl } from '@services/config/config';
|
||||||
import { Field, Form, Formik } from 'formik';
|
import { Field, Form, Formik } from 'formik';
|
||||||
import { updateOrganization } from '@services/settings/org';
|
import { updateOrganization } from '@services/settings/org';
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import React from "react";
|
||||||
import { Title } from "../../components/UI/Elements/Styles/Title";
|
import { Title } from "../../components/UI/Elements/Styles/Title";
|
||||||
import { deleteOrganizationFromBackend } from "@services/organizations/orgs";
|
import { deleteOrganizationFromBackend } from "@services/organizations/orgs";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { swrFetcher } from "@services/utils/requests";
|
import { swrFetcher } from "@services/utils/ts/requests";
|
||||||
import { getAPIUrl, getUriWithOrg } from "@services/config/config";
|
import { getAPIUrl, getUriWithOrg } from "@services/config/config";
|
||||||
import AuthProvider from "@components/Security/AuthProvider";
|
import AuthProvider from "@components/Security/AuthProvider";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { getDefaultOrg, getSelfHostedOption } from "@services/config/config";
|
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
|
@ -15,13 +15,16 @@ export const config = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function middleware(req: NextRequest) {
|
|
||||||
const url = req.nextUrl;
|
|
||||||
const isSelfHosted = getSelfHostedOption();
|
|
||||||
const hostname = req.headers.get("host") || "learnhouse.app";
|
|
||||||
let currentHost = hostname.replace(".localhost:3000", "");
|
|
||||||
|
|
||||||
if (!isSelfHosted && currentHost === "localhost:3000" && !url.pathname.startsWith("/organizations")) {
|
export default function middleware(req: NextRequest) {
|
||||||
|
const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN;
|
||||||
|
const url = req.nextUrl;
|
||||||
|
const isSelfHosted = process.env.NEXT_PUBLIC_LEARNHOUSE_SELF_HOSTED === "true" ? true : false
|
||||||
|
const hostname = req.headers.get("host") || "learnhouse.app";
|
||||||
|
const defaultOrg = isSelfHosted ? process.env.NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG : null;
|
||||||
|
let currentHost = hostname.replace(`.${LEARNHOUSE_DOMAIN}`, "");
|
||||||
|
|
||||||
|
if (!isSelfHosted && currentHost === LEARNHOUSE_DOMAIN && !url.pathname.startsWith("/organizations")) {
|
||||||
// Redirect to error page if not self-hosted and on localhost
|
// Redirect to error page if not self-hosted and on localhost
|
||||||
const errorUrl = "/error";
|
const errorUrl = "/error";
|
||||||
return NextResponse.redirect(errorUrl, { status: 302 });
|
return NextResponse.redirect(errorUrl, { status: 302 });
|
||||||
|
|
@ -42,7 +45,7 @@ export default function middleware(req: NextRequest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSelfHosted) {
|
if (isSelfHosted) {
|
||||||
currentHost = getDefaultOrg() || currentHost;
|
currentHost = defaultOrg || currentHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
url.pathname = `/_orgs/${currentHost}${url.pathname}`;
|
url.pathname = `/_orgs/${currentHost}${url.pathname}`;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"framer-motion": "^7.3.6",
|
"framer-motion": "^7.3.6",
|
||||||
"lucide-react": "^0.104.1",
|
"lucide-react": "^0.104.1",
|
||||||
"next": "^13.2.0",
|
"next": "^13.2.4",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
export async function uploadNewImageFile(file: any, activity_id: string) {
|
export async function uploadNewImageFile(file: any, activity_id: string) {
|
||||||
// Send file thumbnail as form data
|
// Send file thumbnail as form data
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
export async function uploadNewPDFFile(file: any, activity_id: string) {
|
export async function uploadNewPDFFile(file: any, activity_id: string) {
|
||||||
// Send file thumbnail as form data
|
// Send file thumbnail as form data
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
|
|
||||||
export async function submitQuizBlock(activity_id: string, data: any) {
|
export async function submitQuizBlock(activity_id: string, data: any) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
export async function uploadNewVideoFile(file: any, activity_id: string) {
|
export async function uploadNewVideoFile(file: any, activity_id: string) {
|
||||||
// Send file thumbnail as form data
|
// Send file thumbnail as form data
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
const LEARNHOUSE_API_URL = "http://localhost:1338/api/";
|
const LEARNHOUSE_HTTP_PROTOCOL = process.env.NEXT_PUBLIC_LEARNHOUSE_HTTPS === "true" ? "https://" : "http://";
|
||||||
const LEARNHOUSE_BACKEND_URL = "http://localhost:1338/";
|
const LEARNHOUSE_API_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_API_URL}`;
|
||||||
|
const LEARNHOUSE_BACKEND_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL}`;
|
||||||
|
export const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN;
|
||||||
|
|
||||||
export const getAPIUrl = () => LEARNHOUSE_API_URL;
|
export const getAPIUrl = () => LEARNHOUSE_API_URL;
|
||||||
export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL;
|
export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL;
|
||||||
|
|
@ -7,11 +9,10 @@ export const getSelfHostedOption = () => (process.env.NEXT_PUBLIC_LEARNHOUSE_SEL
|
||||||
|
|
||||||
export const getUriWithOrg = (orgslug: string, path: string) => {
|
export const getUriWithOrg = (orgslug: string, path: string) => {
|
||||||
const selfHosted = getSelfHostedOption();
|
const selfHosted = getSelfHostedOption();
|
||||||
|
|
||||||
if (selfHosted) {
|
if (selfHosted) {
|
||||||
return `http://localhost:3000${path}`;
|
return `${LEARNHOUSE_DOMAIN}${path}`;
|
||||||
}
|
}
|
||||||
return `http://${orgslug}.localhost:3000${path}`;
|
return `${LEARNHOUSE_HTTP_PROTOCOL}${orgslug}.${LEARNHOUSE_DOMAIN}${path}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOrgFromUri = () => {
|
export const getOrgFromUri = () => {
|
||||||
|
|
@ -22,7 +23,7 @@ export const getOrgFromUri = () => {
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const hostname = window.location.hostname;
|
const hostname = window.location.hostname;
|
||||||
|
|
||||||
return hostname.replace(".localhost", "");
|
return hostname.replace(`.${LEARNHOUSE_DOMAIN}`, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
export async function createActivity(data: any, chapter_id: any, org_id: any) {
|
export async function createActivity(data: any, chapter_id: any, org_id: any) {
|
||||||
data.content = {};
|
data.content = {};
|
||||||
// remove chapter_id from data
|
// remove chapter_id from data
|
||||||
delete data.chapterId;
|
delete data.chapterId;
|
||||||
|
|
||||||
|
const result = await fetch(`${getAPIUrl()}activities/?coursechapter_id=${chapter_id}&org_id=${org_id}`, RequestBody("POST", data));
|
||||||
const result: any = await fetch(`${getAPIUrl()}activities/?coursechapter_id=${chapter_id}&org_id=${org_id}`, RequestBody("POST", data))
|
const res = await result.json();
|
||||||
.then((result) => result.json())
|
return res;
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
|
|
||||||
console.log("result", result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createFileActivity(file: File, type: string, data: any, chapter_id: any) {
|
export async function createFileActivity(file: File, type: string, data: any, chapter_id: any) {
|
||||||
|
|
@ -29,27 +24,19 @@ export async function createFileActivity(file: File, type: string, data: any, ch
|
||||||
endpoint = `${getAPIUrl()}activities/video`;
|
endpoint = `${getAPIUrl()}activities/video`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: any = await fetch(endpoint, RequestBodyForm("POST", formData))
|
const result: any = await fetch(endpoint, RequestBodyForm("POST", formData));
|
||||||
.then((result) => result.json())
|
const res = await result.json();
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
console.log("result", result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getActivity(activity_id: any) {
|
export async function getActivity(activity_id: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("GET", null))
|
const result = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("GET", null));
|
||||||
.then((result) => result.json())
|
const res = await result.json();
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateActivity(data: any, activity_id: any) {
|
export async function updateActivity(data: any, activity_id: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("PUT", data))
|
const result = await fetch(`${getAPIUrl()}activities/${activity_id}`, RequestBody("PUT", data));
|
||||||
.then((result) => result.json())
|
const res = await result.json();
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { RequestBody } from "@services/utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -8,21 +8,18 @@ import { getAPIUrl } from "@services/config/config";
|
||||||
|
|
||||||
export async function startCourse(course_id: string, org_slug: string) {
|
export async function startCourse(course_id: string, org_slug: string) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_course/${course_id}`, RequestBody("POST", null))
|
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_course/${course_id}`, RequestBody("POST", null))
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeCourse(course_id: string, org_slug: string) {
|
export async function removeCourse(course_id: string, org_slug: string) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/remove_course/${course_id}`, RequestBody("POST", null))
|
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/remove_course/${course_id}`, RequestBody("POST", null))
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function markActivityAsComplete(org_slug: string, course_id: string, activity_id: string) {
|
export async function markActivityAsComplete(org_slug: string, course_id: string, activity_id: string) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_activity/course_id/${course_id}/activity_id/${activity_id}`, RequestBody("POST", null))
|
const result: any = await fetch(`${getAPIUrl()}trail/org_slug/${org_slug}/add_activity/course_id/${course_id}/activity_id/${activity_id}`, RequestBody("POST", null))
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { initialData } from "../../components/Pages/CourseEdit/Draggables/data";
|
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody } from "@services/utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -9,38 +8,26 @@ import { RequestBody } from "@services/utils/requests";
|
||||||
|
|
||||||
//TODO : depreciate this function
|
//TODO : depreciate this function
|
||||||
export async function getCourseChaptersMetadata(course_id: any) {
|
export async function getCourseChaptersMetadata(course_id: any) {
|
||||||
const response = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null));
|
const result = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("GET", null));
|
||||||
|
const res = await errorHandling(result);
|
||||||
if (!response.ok) {
|
return res;
|
||||||
const error: any = new Error(`Error ${response.status}: ${response.statusText}`, {});
|
|
||||||
error.status = response.status;
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateChaptersMetadata(course_id: any, data: any) {
|
export async function updateChaptersMetadata(course_id: any, data: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("PUT", data))
|
const result: any = await fetch(`${getAPIUrl()}chapters/meta/course_${course_id}`, RequestBody("PUT", data));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createChapter(data: any, course_id: any) {
|
export async function createChapter(data: any, course_id: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}chapters/?course_id=course_${course_id}`, RequestBody("POST", data))
|
const result: any = await fetch(`${getAPIUrl()}chapters/?course_id=course_${course_id}`, RequestBody("POST", data));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
|
|
||||||
return result;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteChapter(coursechapter_id: any) {
|
export async function deleteChapter(coursechapter_id: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}chapters/${coursechapter_id}`, RequestBody("DELETE", null))
|
const result: any = await fetch(`${getAPIUrl()}chapters/${coursechapter_id}`, RequestBody("DELETE", null));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "../config/config";
|
import { getAPIUrl } from "../config/config";
|
||||||
import { RequestBody } from "../utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -7,14 +7,14 @@ import { RequestBody } from "../utils/requests";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function deleteCollection(collection_id: any) {
|
export async function deleteCollection(collection_id: any) {
|
||||||
return fetch(`${getAPIUrl()}collections/${collection_id}`, RequestBody("DELETE", null))
|
const result: any = await fetch(`${getAPIUrl()}collections/${collection_id}`, RequestBody("DELETE", null));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new collection
|
// Create a new collection
|
||||||
export async function createCollection(collection: any) {
|
export async function createCollection(collection: any) {
|
||||||
return fetch(`${getAPIUrl()}collections/`, RequestBody("POST", collection))
|
const result: any = await fetch(`${getAPIUrl()}collections/`, RequestBody("POST", collection));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
import { RequestBody, RequestBodyForm, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -7,23 +7,18 @@ import { RequestBody, RequestBodyForm } from "@services/utils/requests";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function getOrgCourses(org_id: number) {
|
export async function getOrgCourses(org_id: number) {
|
||||||
|
const result: any = await fetch(`${getAPIUrl()}courses/${org_id}/page/1/limit/10`, RequestBody("GET", null));
|
||||||
|
const res = await errorHandling(result);
|
||||||
return fetch(`${getAPIUrl()}courses/${org_id}/page/1/limit/10`, RequestBody("GET", null))
|
return res;
|
||||||
.then((result) => result.json())
|
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCourse(course_id: string) {
|
export async function getCourse(course_id: string) {
|
||||||
// todo : add course id to url
|
const result: any = await fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("GET", null));
|
||||||
return fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("GET", null))
|
const res = await errorHandling(result);
|
||||||
.then((result) => result.json())
|
return res;
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function createNewCourse(org_id: string, course_body: any, thumbnail: any) {
|
export async function createNewCourse(org_id: string, course_body: any, thumbnail: any) {
|
||||||
|
|
||||||
// Send file thumbnail as form data
|
// Send file thumbnail as form data
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("thumbnail", thumbnail);
|
formData.append("thumbnail", thumbnail);
|
||||||
|
|
@ -32,16 +27,13 @@ export async function createNewCourse(org_id: string, course_body: any, thumbnai
|
||||||
formData.append("mini_description", "course_body.mini_description");
|
formData.append("mini_description", "course_body.mini_description");
|
||||||
formData.append("public", "true");
|
formData.append("public", "true");
|
||||||
|
|
||||||
|
const result = await fetch(`${getAPIUrl()}courses/?org_id=${org_id}`, RequestBodyForm("POST", formData));
|
||||||
return fetch(`${getAPIUrl()}courses/?org_id=${org_id}`, RequestBodyForm("POST", formData))
|
const res = await errorHandling(result);
|
||||||
.then((result) => result.json())
|
return res;
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteCourseFromBackend(course_id: any) {
|
export async function deleteCourseFromBackend(course_id: any) {
|
||||||
|
const result: any = await fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("DELETE", null));
|
||||||
|
const res = await errorHandling(result);
|
||||||
return fetch(`${getAPIUrl()}courses/${course_id}`, RequestBody("DELETE", null))
|
return res;
|
||||||
.then((result) => result.json())
|
|
||||||
.catch((error) => console.log("error", error));
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody } from "../utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -7,19 +7,19 @@ import { RequestBody } from "../utils/requests";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function createNewOrganization(body: any) {
|
export async function createNewOrganization(body: any) {
|
||||||
return fetch(`${getAPIUrl()}orgs/`, RequestBody("POST", body))
|
const result = await fetch(`${getAPIUrl()}orgs/`, RequestBody("POST", body));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteOrganizationFromBackend(org_id: any) {
|
export async function deleteOrganizationFromBackend(org_id: any) {
|
||||||
return fetch(`${getAPIUrl()}orgs/${org_id}`, RequestBody("DELETE", null))
|
const result = await fetch(`${getAPIUrl()}orgs/${org_id}`, RequestBody("DELETE", null));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOrganizationContextInfo(org_slug: any) {
|
export async function getOrganizationContextInfo(org_slug: any) {
|
||||||
return fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null))
|
const result = await fetch(`${getAPIUrl()}orgs/slug/${org_slug}`, RequestBody("GET", null));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody } from "@services/utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
GET requests are called from the frontend using SWR (https://swr.vercel.app/)
|
GET requests are called from the frontend using SWR (https://swr.vercel.app/)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function updateOrganization(org_id : string, data: any) {
|
export async function updateOrganization(org_id: string, data: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}orgs/` + org_id, RequestBody("PUT", data))
|
const result: any = await fetch(`${getAPIUrl()}orgs/` + org_id, RequestBody("PUT", data));
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody } from "@services/utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -8,8 +8,6 @@ import { RequestBody } from "@services/utils/requests";
|
||||||
|
|
||||||
export async function updatePassword(user_id : string, data: any) {
|
export async function updatePassword(user_id : string, data: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}users/password/user_id/` + user_id, RequestBody("PUT", data))
|
const result: any = await fetch(`${getAPIUrl()}users/password/user_id/` + user_id, RequestBody("PUT", data))
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { getAPIUrl } from "@services/config/config";
|
import { getAPIUrl } from "@services/config/config";
|
||||||
import { RequestBody } from "@services/utils/requests";
|
import { RequestBody, errorHandling } from "@services/utils/ts/requests";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file includes only POST, PUT, DELETE requests
|
This file includes only POST, PUT, DELETE requests
|
||||||
|
|
@ -8,8 +8,6 @@ import { RequestBody } from "@services/utils/requests";
|
||||||
|
|
||||||
export async function updateProfile(data: any) {
|
export async function updateProfile(data: any) {
|
||||||
const result: any = await fetch(`${getAPIUrl()}users/user_id/` + data.user_id, RequestBody("PUT", data))
|
const result: any = await fetch(`${getAPIUrl()}users/user_id/` + data.user_id, RequestBody("PUT", data))
|
||||||
.then((result) => result.json())
|
const res = await errorHandling(result);
|
||||||
.catch((error) => console.log("error", error));
|
return res;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
front/services/utils/react/middlewares/views.ts
Normal file
14
front/services/utils/react/middlewares/views.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context";
|
||||||
|
import { NextRouter } from "next/router";
|
||||||
|
|
||||||
|
export const denyAccessToUser = (error : any, router: AppRouterInstance) => {
|
||||||
|
if (error.status === 401) {
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.status === 403) {
|
||||||
|
router.push("/login");
|
||||||
|
// TODO : add a message to the user to tell him he is not allowed to access this page, route to /error
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context";
|
||||||
|
import { denyAccessToUser } from "../react/middlewares/views";
|
||||||
|
|
||||||
export const RequestBody = (method: string, data: any) => {
|
export const RequestBody = (method: string, data: any) => {
|
||||||
let HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
let HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
||||||
let options: any = {
|
let options: any = {
|
||||||
|
|
@ -24,7 +27,7 @@ export const RequestBodyForm = (method: string, data: any) => {
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const swrFetcher = async (url: string, body: any) => {
|
export const swrFetcher = async (url: string, body: any, router?: AppRouterInstance) => {
|
||||||
// Create the request options
|
// Create the request options
|
||||||
let HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
let HeadersConfig = new Headers({ "Content-Type": "application/json" });
|
||||||
let options: any = {
|
let options: any = {
|
||||||
|
|
@ -39,15 +42,26 @@ export const swrFetcher = async (url: string, body: any) => {
|
||||||
options.body = JSON.stringify(body);
|
options.body = JSON.stringify(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// Fetch the data
|
// Fetch the data
|
||||||
const res = await fetch(url, options);
|
const request = await fetch(url, options);
|
||||||
|
let res = errorHandling(request);
|
||||||
// If the response is not in the 200 range, throw an error
|
|
||||||
if (!res.ok) {
|
|
||||||
const error = new Error("An error occurred while fetching the data.");
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the data
|
// Return the data
|
||||||
|
return res;
|
||||||
|
} catch (error: any) {
|
||||||
|
if (router) {
|
||||||
|
denyAccessToUser(error, router);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const errorHandling = (res: any) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
const error: any = new Error(`Error ${res.status}: ${res.statusText}`, {});
|
||||||
|
error.status = res.status;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
return res.json();
|
return res.json();
|
||||||
};
|
};
|
||||||
|
|
@ -2,16 +2,19 @@ import logging
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
import motor.motor_asyncio
|
import motor.motor_asyncio
|
||||||
|
|
||||||
async def connect_to_db(app: FastAPI) :
|
|
||||||
|
async def connect_to_db(app: FastAPI):
|
||||||
logging.info("Connecting to database...")
|
logging.info("Connecting to database...")
|
||||||
try:
|
try:
|
||||||
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://learnhouse:learnhouse@mongo:27017/") # type: ignore
|
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore
|
||||||
|
app.learnhouse_config.database_config.mongodb_connection_string) # type: ignore
|
||||||
app.db = app.mongodb_client["learnhouse"] # type: ignore
|
app.db = app.mongodb_client["learnhouse"] # type: ignore
|
||||||
logging.info("Connected to database!")
|
logging.info("Connected to database!")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Failed to connect to database!")
|
logging.error("Failed to connect to database!")
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
|
|
||||||
|
|
||||||
async def close_database(app: FastAPI):
|
async def close_database(app: FastAPI):
|
||||||
app.mongodb_client.close() # type: ignore
|
app.mongodb_client.close() # type: ignore
|
||||||
logging.info("LearnHouse has been shut down.")
|
logging.info("LearnHouse has been shut down.")
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
from config.config import LearnHouseConfig, get_learnhouse_config
|
||||||
from src.core.events.database import close_database, connect_to_db
|
from src.core.events.database import close_database, connect_to_db
|
||||||
from src.core.events.logs import create_logs_dir
|
from src.core.events.logs import create_logs_dir
|
||||||
|
|
||||||
|
|
||||||
def startup_app(app: FastAPI) -> Callable:
|
def startup_app(app: FastAPI) -> Callable:
|
||||||
async def start_app() -> None:
|
async def start_app() -> None:
|
||||||
|
# Get LearnHouse Config
|
||||||
|
learnhouse_config: LearnHouseConfig = get_learnhouse_config()
|
||||||
|
app.learnhouse_config = learnhouse_config # type: ignore
|
||||||
|
|
||||||
# Connect to database
|
# Connect to database
|
||||||
await connect_to_db(app)
|
await connect_to_db(app)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ async def verify_rights(request: Request, course_id: str, current_user: PublicUs
|
||||||
|
|
||||||
course = await courses.find_one({"course_id": course_id})
|
course = await courses.find_one({"course_id": course_id})
|
||||||
|
|
||||||
if current_user.user_id == "anonymous" and course["public"] == True:
|
if current_user.user_id == "anonymous" and course["public"] == True and action == "read":
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not course:
|
if not course:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
import requests
|
import requests
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from fileinput import filename
|
from fileinput import filename
|
||||||
|
|
@ -183,7 +184,13 @@ async def create_initial_data(request: Request):
|
||||||
name_in_disk = f"test_mock{course_id}.jpeg"
|
name_in_disk = f"test_mock{course_id}.jpeg"
|
||||||
|
|
||||||
image = requests.get(
|
image = requests.get(
|
||||||
"https://source.unsplash.com/random/800x600")
|
"https://source.unsplash.com/random/800x600/?img=1")
|
||||||
|
|
||||||
|
# check if folder exists and create it if not
|
||||||
|
if not os.path.exists(f"content/uploads/img"):
|
||||||
|
|
||||||
|
os.makedirs(f"content/uploads/img")
|
||||||
|
|
||||||
with open(f"content/uploads/img/{name_in_disk}", "wb") as f:
|
with open(f"content/uploads/img/{name_in_disk}", "wb") as f:
|
||||||
f.write(image.content)
|
f.write(image.content)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue