├── worker └── content-moderation │ ├── logs │ └── .gitkeep │ ├── .gitignore │ ├── packages │ └── clamav │ │ ├── health.sh │ │ ├── Dockerfile │ │ ├── entrypoint.sh │ │ └── THIRD-PARTY │ ├── scripts │ ├── format-scripts.sh │ └── format.sh │ ├── app │ ├── requirements.txt │ ├── scanner │ │ ├── antivirus.py │ │ ├── scan.py │ │ └── nsfw_image.py │ ├── .dockerignore │ ├── Dockerfile │ ├── utils │ │ └── logger.py │ └── main.py │ ├── .env.example │ └── compose.yml ├── ui ├── .prettierignore ├── .eslintrc.json ├── public │ ├── popsound.mp3 │ ├── secure.png │ ├── byteshare.png │ ├── byteshare-white.png │ ├── svg │ │ ├── waves.svg │ │ ├── box.svg │ │ ├── hero.svg │ │ ├── hero_desktop.svg │ │ └── hero_mobile.svg │ └── json │ │ └── terms-page-data.json ├── src │ ├── app │ │ ├── favicon.ico │ │ ├── (pages) │ │ │ ├── auth │ │ │ │ ├── privacy │ │ │ │ │ └── page.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── logout │ │ │ │ │ └── page.tsx │ │ │ │ ├── verify-email │ │ │ │ │ └── page.tsx │ │ │ │ ├── terms │ │ │ │ │ └── page.tsx │ │ │ │ ├── reset-password │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── components │ │ │ │ │ │ └── reset-form.tsx │ │ │ │ ├── forgot-password │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── components │ │ │ │ │ │ └── forgot-form.tsx │ │ │ │ ├── login │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── components │ │ │ │ │ │ └── auth-form.tsx │ │ │ │ └── signup │ │ │ │ │ └── page.tsx │ │ │ ├── share │ │ │ │ └── page.tsx │ │ │ ├── docs │ │ │ │ └── page.tsx │ │ │ ├── (protected) │ │ │ │ └── layout.tsx │ │ │ ├── layout.tsx │ │ │ └── upgrade │ │ │ │ └── page.tsx │ │ ├── robots.ts │ │ ├── layout.tsx │ │ ├── sitemap.ts │ │ ├── not-found.tsx │ │ └── globals.css │ ├── lib │ │ └── utils.ts │ ├── components │ │ ├── line.tsx │ │ ├── ui │ │ │ ├── skeleton.tsx │ │ │ ├── label.tsx │ │ │ ├── textarea.tsx │ │ │ ├── input.tsx │ │ │ ├── progress.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── tooltip.tsx │ │ │ ├── popover.tsx │ │ │ ├── hero-highlight.tsx │ │ │ ├── avatar.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── button.tsx │ │ │ ├── accordion.tsx │ │ │ ├── table.tsx │ │ │ ├── drawer.tsx │ │ │ ├── dialog.tsx │ │ │ ├── alert-dialog.tsx │ │ │ └── navigation-menu.tsx │ │ └── loading.tsx │ ├── context │ │ ├── useAuth.ts │ │ └── authContext.ts │ ├── conf │ │ └── config.ts │ └── authentication │ │ └── appwrite │ │ └── config.ts ├── postcss.config.js ├── .prettierrc.json ├── .env.example ├── next.config.js ├── components.json ├── .gitignore ├── tsconfig.json ├── .dockerignore ├── Dockerfile ├── package.json └── tailwind.config.ts ├── .husky └── pre-commit ├── infrastructure ├── cloud │ ├── terraform.tfvars.example │ └── main.tf └── local │ ├── terraform.tfvars.example │ └── main.tf ├── middleware ├── scripts │ ├── format-scripts.sh │ └── format.sh ├── requirements.txt ├── app │ ├── api │ │ ├── routes │ │ │ ├── access │ │ │ │ ├── main.py │ │ │ │ └── routes │ │ │ │ │ └── aws.py │ │ │ ├── webhook │ │ │ │ ├── main.py │ │ │ │ └── routes │ │ │ │ │ └── user.py │ │ │ ├── secured │ │ │ │ ├── main.py │ │ │ │ └── routes │ │ │ │ │ ├── scan.py │ │ │ │ │ └── developer.py │ │ │ ├── health.py │ │ │ ├── subscribe.py │ │ │ ├── feedback.py │ │ │ └── download.py │ │ ├── services │ │ │ ├── subscribe.py │ │ │ ├── feedback.py │ │ │ ├── health.py │ │ │ ├── webhook │ │ │ │ └── user.py │ │ │ ├── access │ │ │ │ └── aws.py │ │ │ ├── secured │ │ │ │ ├── scan.py │ │ │ │ └── developer.py │ │ │ └── download.py │ │ └── main.py │ ├── utils │ │ ├── helper.py │ │ ├── logger.py │ │ └── auth.py │ ├── main.py │ ├── .env.example │ ├── storage │ │ ├── storage.py │ │ └── cloudflare_r2.py │ └── database │ │ └── db.py ├── samconfig.toml ├── .dockerignore └── Dockerfile ├── .github ├── labeler.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── workflows │ ├── deploy-frontend.yaml │ └── deploy-backend.yaml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── SECURITY.md ├── .env.example ├── LICENSE ├── compose.yml ├── README.md ├── CODE_OF_CONDUCT.md └── CONTRIBUTING.md /worker/content-moderation/logs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .next -------------------------------------------------------------------------------- /ui/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /worker/content-moderation/.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__ 2 | logs/app.log* 3 | .env 4 | .venv -------------------------------------------------------------------------------- /ui/public/popsound.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovencelabs/byteshare/HEAD/ui/public/popsound.mp3 -------------------------------------------------------------------------------- /ui/public/secure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovencelabs/byteshare/HEAD/ui/public/secure.png -------------------------------------------------------------------------------- /ui/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovencelabs/byteshare/HEAD/ui/src/app/favicon.ico -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx -C ui lint-staged 5 | -------------------------------------------------------------------------------- /ui/public/byteshare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovencelabs/byteshare/HEAD/ui/public/byteshare.png -------------------------------------------------------------------------------- /infrastructure/cloud/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | r2_access_key = "" 2 | r2_secret_key = "" 3 | r2_account_id = "" -------------------------------------------------------------------------------- /infrastructure/local/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | r2_access_key = "" 2 | r2_secret_key = "" 3 | r2_account_id = "" -------------------------------------------------------------------------------- /ui/public/byteshare-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/innovencelabs/byteshare/HEAD/ui/public/byteshare-white.png -------------------------------------------------------------------------------- /ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /middleware/scripts/format-scripts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -x 3 | 4 | isort --recursive --force-single-line-imports --apply app 5 | sh ./scripts/format.sh -------------------------------------------------------------------------------- /worker/content-moderation/packages/clamav/health.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! "$(echo PING | nc localhost 3310)" = "PONG" ]; then 4 | echo "ping failed" 5 | exit 1 6 | fi -------------------------------------------------------------------------------- /worker/content-moderation/scripts/format-scripts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -x 3 | 4 | isort --recursive --force-single-line-imports --apply app 5 | sh ./scripts/format.sh -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | "❗️ terraform changes": 2 | - main.tf 3 | - terraform.tfvars.example 4 | 5 | "❗️ .env changes": 6 | - ui/.env.example 7 | - middleware/.env.example -------------------------------------------------------------------------------- /worker/content-moderation/app/requirements.txt: -------------------------------------------------------------------------------- 1 | pika==1.3.2 2 | pyClamd==0.4.0 3 | boto3==1.34.7 4 | requests==2.31.0 5 | tensorflow==2.15.1 6 | pillow==10.3.0 7 | transformers==4.40.1 8 | python-dotenv==1.0.0 -------------------------------------------------------------------------------- /ui/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /middleware/scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -x 3 | 4 | autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place app --exclude=__init__.py 5 | black app 6 | isort --recursive --apply app -------------------------------------------------------------------------------- /ui/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "bracketSpacing": true, 7 | "arrowParens": "always", 8 | "tabWidth": 2 9 | } 10 | -------------------------------------------------------------------------------- /worker/content-moderation/scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | set -x 3 | 4 | autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place app --exclude=__init__.py 5 | black app 6 | isort --recursive --apply app -------------------------------------------------------------------------------- /ui/.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_API_BASE_URL=http://localhost:8000 2 | NEXT_PUBLIC_API_KEY=thisisthekey 3 | NEXT_PUBLIC_APP_URL=http://localhost:3000 4 | NEXT_PUBLIC_APPWRITE_URL=https://cloud.appwrite.io/v1 5 | NEXT_PUBLIC_APPWRITE_PROJECT_ID= -------------------------------------------------------------------------------- /middleware/requirements.txt: -------------------------------------------------------------------------------- 1 | uvicorn==0.29.0 2 | fastapi==0.110.2 3 | boto3==1.34.87 4 | botocore==1.34.87 5 | six==1.16.0 6 | mangum==0.17.0 7 | qrcode==7.4.2 8 | python-dotenv==1.0.0 9 | resend==0.8.0 10 | appwrite==5.0.2 11 | pika==1.3.2 -------------------------------------------------------------------------------- /ui/src/components/line.tsx: -------------------------------------------------------------------------------- 1 | 2 | const HorizontalLine = () => { 3 | return ( 4 |
5 |
6 |
7 | ) 8 | } 9 | 10 | export default HorizontalLine 11 | -------------------------------------------------------------------------------- /ui/src/context/useAuth.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import AuthContext from './authContext' 3 | 4 | const useAuth = () => { 5 | const data = useContext(AuthContext) 6 | return data 7 | } 8 | 9 | export default useAuth 10 | -------------------------------------------------------------------------------- /ui/src/app/(pages)/auth/privacy/page.tsx: -------------------------------------------------------------------------------- 1 | 2 | function PrivacyPage() { 3 | return ( 4 |
5 |

Coming Soon

6 |
7 | ) 8 | } 9 | 10 | export default PrivacyPage 11 | -------------------------------------------------------------------------------- /middleware/app/api/routes/access/main.py: -------------------------------------------------------------------------------- 1 | from api.routes.access.routes import aws 2 | from fastapi import APIRouter 3 | 4 | access_api_router = APIRouter(prefix="/access") 5 | 6 | access_api_router.include_router(aws.router, prefix="/aws", tags=["AWS API access"]) 7 | -------------------------------------------------------------------------------- /middleware/app/api/routes/webhook/main.py: -------------------------------------------------------------------------------- 1 | from api.routes.webhook.routes import user 2 | from fastapi import APIRouter 3 | 4 | webhook_api_router = APIRouter(prefix="/webhook") 5 | 6 | webhook_api_router.include_router(user.router, prefix="/user", tags=["User Routes"]) 7 | -------------------------------------------------------------------------------- /ui/src/conf/config.ts: -------------------------------------------------------------------------------- 1 | const conf = { 2 | appwriteUrl: String(process.env.NEXT_PUBLIC_APPWRITE_URL), 3 | appwriteProjectID: String(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID), 4 | apiBaseUrl: String(process.env.NEXT_PUBLIC_API_BASE_URL), 5 | } 6 | 7 | export default conf 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__ 2 | **/.venv 3 | ui/node_modules 4 | middleware/.aws-sam 5 | middleware/python-site-packages.zip 6 | .terraform 7 | .terraform.lock.hcl 8 | terraform.tfstate 9 | terraform.tfstate.backup 10 | **/.env 11 | todo.txt 12 | ui-bkp 13 | **/.next 14 | issue.txt 15 | terraform.tfvars -------------------------------------------------------------------------------- /worker/content-moderation/.env.example: -------------------------------------------------------------------------------- 1 | VERSION=0.1.0 2 | R2_ACCOUNT_ID= 3 | R2_BUCKET_NAME= 4 | R2_ACCESS_KEY= 5 | R2_SECRET_KEY= 6 | RABBITMQ_QUEUE= 7 | RABBITMQ_URL= 8 | MIDDLEWARE_BASE_URL= 9 | MIDDLEWARE_API_KEY= 10 | CLAMAV_HOST=clamav 11 | NSFW_IMAGE_THRESHOLD=0.6 12 | SCAN_USER= 13 | SCAN_PASS= -------------------------------------------------------------------------------- /ui/src/app/(pages)/share/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useRouter } from 'next/navigation' 4 | import { useEffect } from 'react' 5 | 6 | function Share() { 7 | const router = useRouter() 8 | useEffect(() => { 9 | return router.push('/') 10 | }) 11 | } 12 | 13 | export default Share 14 | -------------------------------------------------------------------------------- /ui/src/app/(pages)/auth/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useRouter } from 'next/navigation' 4 | import { useEffect } from 'react' 5 | 6 | function Auth() { 7 | const router = useRouter() 8 | useEffect(() => { 9 | return router.push('/auth/login') 10 | }) 11 | } 12 | 13 | export default Auth 14 | -------------------------------------------------------------------------------- /ui/src/app/(pages)/docs/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useRouter } from 'next/navigation' 4 | import { useEffect } from 'react' 5 | 6 | function Docs() { 7 | const router = useRouter() 8 | useEffect(() => { 9 | return router.push('/docs/developers') 10 | }) 11 | } 12 | 13 | export default Docs 14 | -------------------------------------------------------------------------------- /ui/src/app/robots.ts: -------------------------------------------------------------------------------- 1 | import { MetadataRoute } from 'next' 2 | 3 | export default function robots(): MetadataRoute.Robots { 4 | return { 5 | rules: { 6 | userAgent: '*', 7 | allow: '/', 8 | disallow: ['/history', '/share/*'], 9 | }, 10 | sitemap: 'https://byteshare.io/sitemap.xml', 11 | } 12 | } -------------------------------------------------------------------------------- /ui/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /worker/content-moderation/app/scanner/antivirus.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pyclamd 4 | from dotenv import load_dotenv 5 | 6 | load_dotenv() 7 | 8 | cd = pyclamd.ClamdNetworkSocket(os.getenv("CLAMAV_HOST"), 3310) 9 | 10 | 11 | def scan_virus(file_stream): 12 | result = cd.scan_stream(file_stream) 13 | 14 | if result: 15 | return False 16 | 17 | return True 18 | -------------------------------------------------------------------------------- /middleware/samconfig.toml: -------------------------------------------------------------------------------- 1 | version = 0.1 2 | [default] 3 | [default.global] 4 | [default.global.parameters] 5 | stack_name = "sam-byteshare-prod" 6 | resolve_s3 = true 7 | s3_prefix = "sam-byteshare-prod" 8 | region = "us-east-2" 9 | confirm_changeset = false 10 | capabilities = "CAPABILITY_IAM" 11 | parameter_overrides = "LamdbaLayerName=\"byteshare-dependencies\"" 12 | image_repositories = [] 13 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Contact us at security@byteshare.io 4 | 5 | ## Supported Versions 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 1.x | :white_check_mark: | 10 | 11 | ## Reporting a Vulnerability 12 | 13 | In case of security issue 14 | 15 | - Email your findings to security@byteshare.io. 16 | - Do not post to public issue on GitHub. 17 | -------------------------------------------------------------------------------- /middleware/app/api/routes/secured/main.py: -------------------------------------------------------------------------------- 1 | from api.routes.secured.routes import developer, scan 2 | from fastapi import APIRouter 3 | 4 | secured_api_router = APIRouter(prefix="/secured") 5 | 6 | secured_api_router.include_router(scan.router, prefix="/scan", tags=["Scan Routes"]) 7 | secured_api_router.include_router( 8 | developer.router, prefix="/developer", tags=["Developer Routes"] 9 | ) 10 | -------------------------------------------------------------------------------- /ui/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const environment = process.env.NEXT_PUBLIC_ENVIRONMENT || "production" 3 | 4 | const nextConfig = { 5 | images: { 6 | remotePatterns: [ 7 | { 8 | protocol: 'https', 9 | hostname: '**', 10 | }, 11 | ], 12 | }, 13 | ...(environment === 'dev' && { output: 'standalone' }), 14 | } 15 | 16 | module.exports = nextConfig 17 | -------------------------------------------------------------------------------- /ui/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /middleware/app/utils/helper.py: -------------------------------------------------------------------------------- 1 | def get_file_extension(file_name): 2 | return file_name.split(".")[-1] 3 | 4 | 5 | def format_size(byte_size): 6 | if byte_size < 1024: 7 | return f"{byte_size} B" 8 | elif byte_size < 1024**2: 9 | return f"{byte_size / 1024:.2f} KB" 10 | elif byte_size < 1024**3: 11 | return f"{byte_size / (1024 ** 2):.2f} MB" 12 | else: 13 | return f"{byte_size / (1024 ** 3):.2f} GB" 14 | -------------------------------------------------------------------------------- /ui/src/context/authContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react' 2 | 3 | export const AuthContext = createContext<{ 4 | authorised: boolean 5 | setAuthorised: (status: boolean) => void 6 | statusLoaded: boolean 7 | setStatusLoaded: (status: boolean) => void 8 | }>({ 9 | authorised: false, 10 | setAuthorised: () => {}, 11 | statusLoaded: false, 12 | setStatusLoaded: () => {}, 13 | }) 14 | 15 | export const AuthProvider = AuthContext.Provider 16 | 17 | export default AuthContext 18 | -------------------------------------------------------------------------------- /ui/src/app/(pages)/auth/logout/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import appwriteService from '@/authentication/appwrite/config' 4 | import useAuth from '@/context/useAuth' 5 | import { useRouter } from 'next/navigation' 6 | 7 | function Logout() { 8 | const router = useRouter() 9 | const { authorised, setAuthorised } = useAuth() 10 | 11 | if (authorised) { 12 | appwriteService.logout() 13 | setAuthorised(false) 14 | router.push('/') 15 | } 16 | 17 | return <> 18 | } 19 | 20 | export default Logout 21 | -------------------------------------------------------------------------------- /worker/content-moderation/app/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/__pycache__ 3 | **/.venv 4 | **/.classpath 5 | **/.dockerignore 6 | **/.env 7 | **/.git 8 | **/.gitignore 9 | **/.project 10 | **/.settings 11 | **/.toolstarget 12 | **/.vs 13 | **/.vscode 14 | **/*.*proj.user 15 | **/*.dbmdl 16 | **/*.jfm 17 | **/bin 18 | **/charts 19 | **/docker-compose* 20 | **/compose.y*ml 21 | **/Dockerfile* 22 | **/node_modules 23 | **/npm-debug.log 24 | **/obj 25 | **/secrets.dev.yaml 26 | **/values.dev.yaml 27 | LICENSE 28 | README.md 29 | -------------------------------------------------------------------------------- /middleware/app/main.py: -------------------------------------------------------------------------------- 1 | from api.main import api_router 2 | from fastapi import FastAPI 3 | from fastapi.middleware.cors import CORSMiddleware 4 | from mangum import Mangum 5 | 6 | app = FastAPI() 7 | 8 | # CORS (Cross Origin Resource Sharing) (for local) 9 | app.add_middleware( 10 | CORSMiddleware, 11 | allow_origins=["*"], 12 | allow_credentials=True, 13 | allow_methods=["*"], 14 | allow_headers=["*"], 15 | ) 16 | 17 | app.include_router(api_router) 18 | 19 | # Create a Handler from FastAPI for lambda. 20 | handler = Mangum(app) 21 | -------------------------------------------------------------------------------- /ui/src/app/(pages)/(protected)/layout.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import useAuth from '@/context/useAuth' 3 | import { useRouter } from 'next/navigation' 4 | import React from 'react' 5 | 6 | const ProtectedLayout = ({ children }: { children: React.ReactNode }) => { 7 | const router = useRouter() 8 | const { authorised, statusLoaded } = useAuth() 9 | 10 | if (statusLoaded && !authorised) { 11 | router.push('/auth/login') 12 | } else if (!statusLoaded) { 13 | return <> 14 | } 15 | return children 16 | } 17 | 18 | export default ProtectedLayout 19 | -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /middleware/app/.env.example: -------------------------------------------------------------------------------- 1 | ENVIRONMENT=dev 2 | WEB_BASE_URL=http://localhost:3000 3 | R2_ACCOUNT_ID= 4 | R2_ACCESS_KEY= 5 | R2_SECRET_KEY= 6 | RESEND_API_KEY= 7 | APPWRITE_URL=https://cloud.appwrite.io/v1 8 | APPWRITE_PROJECT_ID= 9 | APPWRITE_API_KEY= 10 | AWS_APP_REGION= 11 | AWS_APP_ACCESS_KEY= 12 | AWS_APP_SECRET_ACCESS_KEY= 13 | RABBITMQ_QUEUE= 14 | RABBITMQ_URL= 15 | APPWRITE_WEBHOOK_USER= 16 | APPWRITE_WEBHOOK_PASS= 17 | SCAN_USER= 18 | SCAN_PASS= 19 | AWS_API_ACCESS_ACCESS_KEY= 20 | AWS_API_ACCESS_SECRET_ACCESS_KEY= 21 | AWS_API_ACCESS_REGION= 22 | AWS_API_ACCESS_ROLE_ARN= 23 | AWS_API_KEY= -------------------------------------------------------------------------------- /ui/public/svg/waves.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /middleware/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | **/__pycache__ 3 | **/.venv 4 | **/.classpath 5 | **/.dockerignore 6 | **/.env 7 | **/.env.example 8 | **/.git 9 | **/.gitignore 10 | **/.project 11 | **/.settings 12 | **/.toolstarget 13 | **/.vs 14 | **/.vscode 15 | **/*.*proj.user 16 | **/*.dbmdl 17 | **/*.jfm 18 | **/bin 19 | **/charts 20 | **/docker-compose* 21 | **/compose.y*ml 22 | **/Dockerfile* 23 | **/node_modules 24 | **/npm-debug.log 25 | **/obj 26 | **/secrets.dev.yaml 27 | **/values.dev.yaml 28 | **/.aws-sam/ 29 | **/samconfig.toml 30 | **/template.yaml 31 | **/docs/ 32 | **/doc/ 33 | **/*.md 34 | scripts/ 35 | LICENSE 36 | README.md 37 | -------------------------------------------------------------------------------- /ui/src/components/loading.tsx: -------------------------------------------------------------------------------- 1 | import { Label } from '@/components/ui/label' 2 | import { useEffect, useState } from 'react' 3 | 4 | const LoadingText = ({text}) => { 5 | const [dots, setDots] = useState('') 6 | 7 | useEffect(() => { 8 | const intervalId = setInterval(() => { 9 | setDots((prevDots) => { 10 | if (prevDots.length >= 3) { 11 | return '' 12 | } else { 13 | return prevDots + '.' 14 | } 15 | }) 16 | }, 500) 17 | 18 | return () => clearInterval(intervalId) 19 | }, []) 20 | 21 | return 22 | } 23 | 24 | export default LoadingText 25 | -------------------------------------------------------------------------------- /middleware/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PYTHON_VERSION=3.10 2 | FROM python:${PYTHON_VERSION}-alpine as base 3 | 4 | ENV PYTHONDONTWRITEBYTECODE=1 5 | ENV PYTHONUNBUFFERED=1 6 | 7 | WORKDIR /app 8 | 9 | ARG UID=10001 10 | RUN adduser \ 11 | --disabled-password \ 12 | --gecos "" \ 13 | --home "/nonexistent" \ 14 | --shell "/sbin/nologin" \ 15 | --no-create-home \ 16 | --uid "${UID}" \ 17 | appuser 18 | 19 | RUN --mount=type=cache,target=/root/.cache/pip \ 20 | --mount=type=bind,source=requirements.txt,target=requirements.txt \ 21 | python -m pip install -r requirements.txt 22 | 23 | USER appuser 24 | 25 | COPY app . 26 | EXPOSE 8000 27 | CMD uvicorn 'main:app' --host=0.0.0.0 --port=8000 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | [A clear and concise description of what the problem is] (e.g., I'm always frustrated when [...]) 12 | 13 | **Describe the solution you'd like** 14 | [A clear and concise description of what you want to happen] 15 | 16 | **Describe alternatives you've considered** 17 | [A clear and concise description of any alternative solutions or features you've considered] 18 | 19 | **Additional context** 20 | [Add any other context or screenshots about the feature request here] 21 | -------------------------------------------------------------------------------- /middleware/app/storage/storage.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class BaseStorage(ABC): 5 | @abstractmethod 6 | def health_check(self): 7 | pass 8 | 9 | @abstractmethod 10 | def generate_upload_url(self, file_path: str, expirations_seconds: int): 11 | pass 12 | 13 | @abstractmethod 14 | def generate_download_url(self, file_path: str, expirations_seconds: int): 15 | pass 16 | 17 | @abstractmethod 18 | def upload_file(self, localpath: str, file_path: str): 19 | pass 20 | 21 | @abstractmethod 22 | def is_file_present(self, file_path): 23 | pass 24 | 25 | @abstractmethod 26 | def get_file_info(self, file_path: str): 27 | pass 28 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | BYTESHARE_VERSION=0.4.2 2 | ENVIRONMENT=dev 3 | NEXT_PUBLIC_API_BASE_URL=http://localhost:8000 4 | NEXT_PUBLIC_APPWRITE_PROJECT_ID= 5 | NEXT_PUBLIC_API_KEY=thisisthekey 6 | WEB_BASE_URL=http://localhost:3000 7 | RESEND_API_KEY= 8 | R2_ACCOUNT_ID= 9 | R2_ACCESS_KEY= 10 | R2_SECRET_KEY= 11 | APPWRITE_URL=https://cloud.appwrite.io/v1 12 | APPWRITE_PROJECT_ID= 13 | APPWRITE_API_KEY= 14 | AWS_APP_REGION= 15 | AWS_APP_ACCESS_KEY= 16 | AWS_APP_SECRET_ACCESS_KEY= 17 | AWS_API_ACCESS_ACCESS_KEY= 18 | AWS_API_ACCESS_SECRET_ACCESS_KEY= 19 | AWS_API_ACCESS_REGION= 20 | AWS_API_ACCESS_ROLE_ARN= 21 | 22 | # Not Required for Development mode 23 | SCAN_USER= 24 | SCAN_PASS= 25 | APPWRITE_WEBHOOK_USER= 26 | APPWRITE_WEBHOOK_PASS= 27 | RABBITMQ_QUEUE= 28 | RABBITMQ_URL= -------------------------------------------------------------------------------- /worker/content-moderation/app/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PYTHON_VERSION=3.10 2 | FROM python:${PYTHON_VERSION} as base 3 | ENV PYTHONDONTWRITEBYTECODE=1 4 | ENV PYTHONUNBUFFERED=1 5 | WORKDIR /app 6 | ARG UID=10001 7 | RUN adduser \ 8 | --disabled-password \ 9 | --gecos "" \ 10 | --home "/nonexistent" \ 11 | --shell "/sbin/nologin" \ 12 | --no-create-home \ 13 | --uid "${UID}" \ 14 | moderator 15 | RUN mkdir -p ./models && chmod 755 ./models 16 | RUN chown moderator:moderator ./models 17 | RUN --mount=type=cache,target=/root/.cache/pip \ 18 | --mount=type=bind,source=requirements.txt,target=requirements.txt \ 19 | python -m pip install -r requirements.txt 20 | USER moderator 21 | ENV HF_HOME=./models 22 | COPY . . 23 | CMD python main.py 24 | -------------------------------------------------------------------------------- /middleware/app/api/routes/health.py: -------------------------------------------------------------------------------- 1 | import api.services.health as health_service 2 | import utils.logger as logger 3 | from fastapi import APIRouter 4 | 5 | router = APIRouter() 6 | 7 | # Logger instance 8 | log = logger.get_logger() 9 | 10 | 11 | @router.get("/") 12 | def health_check(): 13 | """ 14 | Perform checks to verify system health. 15 | For instance, check database connection, external services, etc. 16 | 17 | Parameters: 18 | - None 19 | 20 | Returns: 21 | - Status of application and external services 22 | """ 23 | FUNCTION_NAME = "health_check()" 24 | log.info("Entering {}".format(FUNCTION_NAME)) 25 | 26 | response = health_service.health_check() 27 | 28 | log.info("Exiting {}".format(FUNCTION_NAME)) 29 | return response 30 | -------------------------------------------------------------------------------- /ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next", 19 | }, 20 | ], 21 | "baseUrl":".", 22 | "paths": { 23 | "@/*": ["./src/*"], 24 | "public/*": ["public/*"] 25 | }, 26 | }, 27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 28 | "exclude": ["node_modules"], 29 | } 30 | -------------------------------------------------------------------------------- /ui/.dockerignore: -------------------------------------------------------------------------------- 1 | # Include any files or directories that you don't want to be copied to your 2 | # container here (e.g., local build artifacts, temporary files, etc.). 3 | # 4 | # For more help, visit the .dockerignore file reference guide at 5 | # https://docs.docker.com/go/build-context-dockerignore/ 6 | 7 | **/.classpath 8 | **/.dockerignore 9 | **/.env 10 | **/.eslintrc.json 11 | **/.prettierrc.json 12 | **/.git 13 | **/.gitignore 14 | **/.project 15 | **/.settings 16 | **/.toolstarget 17 | **/.vs 18 | **/.vscode 19 | **/.next 20 | **/.cache 21 | **/*.*proj.user 22 | **/*.dbmdl 23 | **/*.jfm 24 | **/charts 25 | **/docker-compose* 26 | **/compose.y*ml 27 | **/Dockerfile* 28 | **/node_modules 29 | **/npm-debug.log 30 | **/obj 31 | **/secrets.dev.yaml 32 | **/values.dev.yaml 33 | **/build 34 | **/dist 35 | LICENSE 36 | README.md 37 | -------------------------------------------------------------------------------- /ui/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as React from 'react' 4 | import * as LabelPrimitive from '@radix-ui/react-label' 5 | import { cva, type VariantProps } from 'class-variance-authority' 6 | 7 | import { cn } from '@/lib/utils' 8 | 9 | const labelVariants = cva( 10 | 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /ui/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |