- LiveView Authentication
- User Role and Permission system
- Direct to S3/Wasabi upload with LiveView
- Generates presigned urls for secure download
- Calculates file hashes with
:crypto.hash/2
Uploads to Triage on upload to Vx Underground via Oban Job Scheduler and notifies the user of completion withPhoenix.Channels
.- Checks for VT Report on load of the
Sample
show page. - Uses
libcluster
andfly_postgres
for scalability - Has CI/CD setup and is deployed on Fly.io.
Custom Discord Logger backend- Upload, login and get sample API routes
- Postgres
- erlang
- Elixir
- Phoenix
- Phoenix LiveView
- NodeJS
- TailwindCSS
-
Install
erlang
,Elixir
,NodeJS
,Postgres
- With homebrew the commands are:
brew update brew install erlang elixir nodejs postgres
- Or if you prefer
asdf
brew update brew install asdf asdf plugin-add erlang asdf plugin-add elixir asdf plugin-add nodejs asdf install
- Clone this Repo and enter the directory.
- Set up the project with the command
mix setup
- Start Phoenix server with
iex -S mix phx.server
- Now you can visit
localhost:4000
orlocalhost:4001
from your browser.
- Now you can visit
- Once you register a user, you make it admin by running this in the same window you ran
iex -S mix phx.server
in (yes we run commands in a running server)VExchange.Accounts.get_user!(1) |> VExchange.Accounts.add_role_to_user("Admin")
You can run unit tests with the command
mix test
Documentation can be found at here and requires an API key generated when a user signs up.
Example script using the upload API to upload all files from a sub directory.
import requests, os, sys
from concurrent.futures import ThreadPoolExecutor
MAX_WORKERS = 10
API_LOGIN = "https://virus.exchange/api/login"
API_UPLOAD = "https://virus.exchange/api/upload"
TOKEN=""
EMAIL="ur email"
if TOKEN == "":
PASSWORD=input("Enter your password: ")
r = requests.post(API_LOGIN, data={"email":EMAIL, "password":PASSWORD})
TOKEN = r.json()["data"]["token"]
def process_file(subdir, file):
filename = os.path.join(subdir, file)
with open(filename, "rb+") as f:
file_content = f.read()
r = requests.post(API_UPLOAD, headers={'Authorization': f"Bearer {TOKEN}", "Content-Type": "application/x-www-form-urlencoded"}, data=file_content)
print(f"{os.path.basename(filename)}: STATUS({r.status_code}) {r.text}")
def main(directory):
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
for subdir, dirs, files in os.walk(directory):
for file in files:
executor.submit(process_file, subdir, file)
if __name__ == '__main__':
main(sys.argv[1])