diff --git a/FileUploaderBot b/FileUploaderBot index 0eb5c25..e58aad2 160000 --- a/FileUploaderBot +++ b/FileUploaderBot @@ -1 +1 @@ -Subproject commit 0eb5c25dda6ad779f5f4ba3f8957b424b06f882c +Subproject commit e58aad2ab2345e61a19dcc35a55e07d608161552 diff --git a/README.md b/README.md index 4bf1ced..7615b1f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The file uploader is implemented in the Python programming language using FastAP ## API Documentation The API is currently hosted at [fu.andcool.ru](https://fu.andcool.ru/). -Page redirection is handled through the nginx proxy server. The API consists of 2 pathes: +Page redirection is handled through the nginx proxy server. The API consists of 2 paths: - `/file/` – Endpoint where all files are located. - `/api/` – Main API endpoint @@ -95,7 +95,7 @@ On successful execution, the API returns a `200` HTTP code along with a JSON res | 400 | No file uploaded | No file is given in the request body | | 413 | File size exceeds the limit (100MB) | The file size exceeds 100MB | | 400 | Invalid group id | `group_id` parameter contains non-numerical value | -| 404 | Group not found | The group wuth provided `group_id` not found | +| 404 | Group not found | The group with provided `group_id` not found | | 403 | You are not in the group | Group is exists, but you are has not permissions to upload files in this group | ### Delete a file @@ -158,7 +158,7 @@ Successful execution returns a `200` HTTP code, indicating successful registrati | 3 | 403 | Wrong password | Incorrect password | | 4 | 404 | User not found | Username not found | -### Refreshe the token +### Refresh the token `POST /api/refresh_token` Request limit per minute: 10 times. The request body includes the `accessToken` field containing only the token (without `Bearer`). @@ -227,7 +227,7 @@ Errors described in section `1.1` may occur as well. | Error Code | message | Possible Reasons | | ---------- | ------------------------ | ------------------------------------------------------------------------------ | | 400 | Invalid group id | `group_id` parameter contains non-numerical value | -| 404 | Group not found | The group wuth provided `group_id` not found | +| 404 | Group not found | The group with provided `group_id` not found | | 403 | You are not in the group | Group is exists, but you are has not permissions to upload files in this group | @@ -258,7 +258,7 @@ It takes the `Authorization` header containing the access token. ```json { "status": "success", - "message": "transfered", + "message": "transferred", "unsuccess": [ { "file_url": "4yn-8yjhsR", @@ -331,7 +331,7 @@ Errors described in section `1.1` may occur as well. | Error Code | message | Possible Reasons | | ---------- | -------------------------------------------------- | -------------------------------------- | | 404 | Group not found | Group with passed `group_id` not found | -| 403 | You dont have any permissions to delete this group | You are not owner of this group | +| 403 | You don't have any permissions to delete this group | You are not owner of this group | ### Generate a new invite link `GET /api/generate_invite/{group_id}` @@ -355,7 +355,7 @@ Errors described in section `1.1` may occur as well. | Error Code | message | Possible Reasons | | ---------- | ----------------------------- | -------------------------------------- | | 404 | Group not found | Group with passed `group_id` not found | -| 403 | You dont have any permissions | You are not owner of this group | +| 403 | You don't have any permissions | You are not owner of this group | ### Join to a group `POST /api/join/{invite_link}` diff --git a/main.py b/main.py index f0f8f9a..73beacf 100644 --- a/main.py +++ b/main.py @@ -2,28 +2,28 @@ created by AndcoolSystems, 2023-2024 """ -from fastapi import FastAPI, UploadFile, Request, Header from fastapi.responses import JSONResponse, FileResponse, Response, RedirectResponse -from typing import Annotated, Union -import uvicorn from config import filetypes, default, accessLifeTime, accessLifeTimeBot, pattern -import aiohttp -import utils -from slowapi.errors import RateLimitExceeded from slowapi import Limiter, _rate_limit_exceeded_handler -from slowapi.util import get_remote_address +from fastapi import FastAPI, UploadFile, Request, Header from fastapi.middleware.cors import CORSMiddleware -import time -import aiofiles -from prisma import Prisma -import uuid -import os -from datetime import datetime +from slowapi.errors import RateLimitExceeded +from slowapi.util import get_remote_address +from typing import Annotated, Union from dotenv import load_dotenv -import jwt +from datetime import datetime +from prisma import Prisma +import aiofiles +import uvicorn +import aiohttp import bcrypt import random +import utils +import time +import uuid import json +import jwt +import os import re @@ -80,7 +80,7 @@ async def api(request: Request): ) -async def check_token(Authorization, user_agent): +async def check_token(Authorization: str, user_agent: str): if not Authorization: # If token doesn't provided return None, {"message": "No Authorization header provided", "errorId": -1} @@ -92,15 +92,11 @@ async def check_token(Authorization, user_agent): } try: - token = jwt.decode( - token_header[1], "accessTokenSecret", algorithms=["HS256"] - ) # Decode token + token = jwt.decode(token_header[1], "accessTokenSecret", algorithms=["HS256"]) # Decode token except jwt.exceptions.DecodeError: return None, {"message": "Invalid access token", "errorId": -4} - token_db = await db.token.find_first( - where={"accessToken": token_header[1]}, include={"user": True} - ) # Find token in db + token_db = await db.token.find_first(where={"accessToken": token_header[1]}, include={"user": True}) # Find token in db if not token_db: # If not found return None, {"message": "Token not found", "errorId": -5} @@ -311,11 +307,8 @@ async def delete_file(url: str, key: str = ""): where={"id": result.id} ) # Delete file record from database - async with aiohttp.ClientSession( - "https://api.cloudflare.com" - ) as session: # Clear file cache from CloudFlare - async with session.post( - f"/client/v4/zones/{os.getenv('ZONE_ID')}/purge_cache", + async with aiohttp.ClientSession("https://api.cloudflare.com") as session: # Clear file cache from CloudFlare + async with session.post(f"/client/v4/zones/{os.getenv('ZONE_ID')}/purge_cache", json={"files": ["https://fu.andcool.ru/file/" + result.url]}, headers={"Authorization": "Bearer " + os.getenv("KEY")}): pass @@ -396,7 +389,7 @@ async def getFiles( "ext": file.ext, "user_filename": user_filename, "creation_date": file.created_date, - "craeted_at": file.craeted_at, + "created_at": file.craeted_at, "size": utils.calculate_size(file.size), "username": usr, "synced": True, @@ -416,7 +409,7 @@ async def getFiles( ) -@app.post("/api/register") # Registartion handler +@app.post("/api/register") # Registration handler @limiter.limit(dynamic_limit_provider) async def register(request: Request, bot: bool = False, user_agent: Union[str, None] = Header(default=None)): try: @@ -444,7 +437,7 @@ async def register(request: Request, bot: bool = False, user_agent: Union[str, N where={"username": body["username"]} ) # Find same username in db - if user: # If iser already exists + if user: # If user already exists return JSONResponse( { "status": "error", @@ -485,7 +478,7 @@ async def register(request: Request, bot: bool = False, user_agent: Union[str, N "status": "success", "accessToken": access, "username": body["username"], - "message": "registred", + "message": "registered", }, status_code=200, ) @@ -789,7 +782,7 @@ async def transfer( except Exception: non_success.append(requested_file) - return {"status": "success", "message": "transfered", "unsuccess": non_success} + return {"status": "success", "message": "transferred", "unsuccess": non_success} # --------------------------------------Groups------------------------------------------ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..27acc93 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +fastapi +slowapi +python-dotenv +prisma +aiofiles +uvicorn +aiohttp +bcrypt +PyJWT \ No newline at end of file diff --git a/web/404/404.html b/web/404/404.html new file mode 100644 index 0000000..c28b84b --- /dev/null +++ b/web/404/404.html @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web/index.html b/web/index.html index 3de974f..5944a57 100644 --- a/web/index.html +++ b/web/index.html @@ -5,7 +5,7 @@ File uploader - + diff --git a/web/res/manifest.webmanifest b/web/res/manifest.webmanifest new file mode 100644 index 0000000..d64a5b9 --- /dev/null +++ b/web/res/manifest.webmanifest @@ -0,0 +1,20 @@ +{ + "name": "File Uploader", + "short_name": "File Upload", + "start_url": "/", + "display": "standalone", + "background_color": "#222222", + "theme_color": "#222222", + "icons": [ + { + "src": "/res/pag.png", + "sizes": "626x626", + "type": "image/png" + } + ], + "orientation": "natural", + "dir": "auto", + "lang": "en", + "id": "fu.andcool", + "description": "Simple File Uploader" + } \ No newline at end of file diff --git a/web/res/pag.png b/web/res/pag.png new file mode 100644 index 0000000..66c8c27 Binary files /dev/null and b/web/res/pag.png differ diff --git a/web/script.js b/web/script.js index 42fe16d..43c1260 100644 --- a/web/script.js +++ b/web/script.js @@ -601,4 +601,3 @@ async function upload(file) { } } -