123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- <?php
- namespace app\Controllers;
- use app\Exceptions\FollowNotFoundException;
- use app\Exceptions\InvalidRequestException;
- use app\Exceptions\UnauthenticatedException;
- use app\Exceptions\VideoNotFoundException;
- use app\Hajeebtok;
- use app\Interfaces\IRouteController;
- use app\Logger;
- use app\Types\DatabaseObjects\Account;
- use app\Types\DatabaseObjects\Follow;
- use app\Types\DatabaseObjects\Link;
- use app\Types\DatabaseObjects\Session;
- use app\Types\LinkEnum;
- use Hajeebtok\Types\Exceptions\SecurityFaultException;
- use Mimey\MimeTypes;
- use Pecee\SimpleRouter\SimpleRouter;
- class AccountController implements IRouteController
- {
- public static function getToken(): string
- {
- $username = input("username");
- $password = password_hash(input("password"), PASSWORD_DEFAULT);
- $account = new Account(
- username: $username,
- password: $password,
- picture_hash: "default",
- verified: false
- );
- if ($account->Exists()) { // Account already exists
- $account->Load();
- if (password_verify($password, $account->password)) throw new UnauthenticatedException($account->id, 401);
- $session = new Session(account_id: $account->id);
- } else { // Create a new account
- $session = new Session(account_id: $account->Save());
- }
- CORSHelper();
- $token = $session->Save();
- $session->Load();
- return api_json([
- "token" => $token,
- "auth_date" => $session->date_authenticated
- ]);
- }
- public static function getAccount($id): string
- {
- Logger::Debug("Getting account id ($id).");
- $account = new Account(id: $id);
- $account->Load();
- $followers = count(new Follow(followee_id: $id)->LoadMany());
- $following = count(new Follow(follower_id: $id)->LoadMany());
- $links = new Link(account_id: $id)->LoadMany();
- return api_json([
- "id" => $id,
- "username" => $account->username,
- "verified" => $account->verified,
- "bio" => $account->bio,
- "pictureHash" => $account->picture_hash,
- "followers" => $followers,
- "following" => $following,
- "links" => $links
- ]);
- }
- public static function search(): string
- {
- $query = input("query");
- $account = new Account(username: $query);
- $accounts = $account->LoadMany();
- return api_json($accounts);
- }
- public static function getVideos($id): string
- {
- $account = new Account(id: $id);
- $data = Hajeebtok::$Database->Query("SELECT * FROM videos WHERE author_id = :author_id", ["author_id" => $account->id]);
- if (empty($data)) throw new VideoNotFoundException(0, 404);
- return api_json($data);
- }
- public static function getPicture($id): string
- {
- $signed_in = signed_in(request());
- if($signed_in) {
- $account = new Account(id: $id);
- $account->Load();
- $picture_path = APP_ROOT . "/usercontent/pictures/$account->picture_hash.png";
- } else {
- // this is hardcoded because i dont care
- $picture_path = APP_ROOT . "/usercontent/pictures/premium_" . rand(1, 57) . ".png";
- }
- $mimeTypes = new MimeTypes();
- $picture_contents = file_get_contents($picture_path);
- $picture_size = filesize($picture_path);
- $mime = $mimeTypes->getMimeType(pathinfo($picture_path, PATHINFO_EXTENSION));
- $response = response();
- $response->header("Content-Type: $mime");
- $response->header("Content-Length: $picture_size");
- $response->header("Cache-Control: max-age=3600, public");
- return $picture_contents;
- }
- public static function getAvailablePremiumProfilePictures(): string
- {
- $pictures = [];
- for ($i = 1; $i <= 57; $i++) {
- $pictures[] = $i;
- }
- return api_json($pictures);
- }
- public static function getPremiumProfilePicture($id): string
- {
- $picture_path = APP_ROOT . "/usercontent/pictures/premium_$id.png";
- $mime_types = new MimeTypes();
- $picture_contents = file_get_contents($picture_path);
- $picture_size = filesize($picture_path);
- $mime = $mime_types->getMimeType(pathinfo($picture_path, PATHINFO_EXTENSION));
- $response = response();
- $response->header("Content-Type: $mime");
- $response->header("Content-Length: $picture_size");
- $response->header("Cache-Control: max-age=3600, public");
- return $picture_contents;
- }
- public static function updateAccount(): string
- {
- if(!signed_in(request())) throw new UnauthenticatedException(0, 401);
- $id = get_token_id(request());
- $picture_hash = input("picture_hash");
- $picture = request()->getInputHandler()->file("picture");
- $bio = input("bio");
- if(empty($picture) && !empty($picture_hash)) {
- $valid_picture_hash_list = [
- "default",
- "premium_1",
- "premium_2",
- "premium_3",
- "premium_4",
- "premium_5",
- "premium_6",
- "premium_7",
- "premium_8",
- "premium_9",
- "premium_10",
- "premium_11",
- "premium_12",
- "premium_13",
- "premium_14",
- "premium_15",
- "premium_16",
- "premium_17",
- "premium_18",
- "premium_19",
- "premium_20",
- "premium_21",
- "premium_22",
- "premium_23",
- "premium_24",
- "premium_25",
- "premium_26",
- "premium_27",
- "premium_28",
- "premium_29",
- "premium_30",
- "premium_31",
- "premium_32",
- "premium_33",
- "premium_34",
- "premium_35",
- "premium_36",
- "premium_37",
- "premium_38",
- "premium_39",
- "premium_40",
- "premium_41",
- "premium_42",
- "premium_43",
- "premium_44",
- "premium_45",
- "premium_46",
- "premium_47",
- "premium_48",
- "premium_49",
- "premium_50",
- "premium_51",
- "premium_52",
- "premium_53",
- "premium_54",
- "premium_55",
- "premium_56",
- "premium_57"
- ];
- if(!in_array($picture_hash, $valid_picture_hash_list)) throw new SecurityFaultException("Attempt to path trace on /update endpoint.",400);
- } else if (!empty($picture) && empty($picture_hash)) {
- $picture_hash = hash("sha256", $picture);
- $picture_path = APP_ROOT . "/usercontent/pictures/$picture_hash.png";
- $size = getimagesize($picture);
- $crop = min($size[0], $size[1]);
- $image_contents = file_get_contents($picture);
- $image_string = imagecreatefromstring($image_contents);
- $cropped_image = imagecrop($image_string, [
- "x" => 0,
- "y" => 0,
- "width" => $crop,
- "height" => $crop
- ]);
- imagepng($cropped_image, $picture_path); // save image and crop and turn into png (i love php)
- } else if(!empty($picture) && !empty($picture_hash)) {
- throw new InvalidRequestException(400);
- }
- $old_account = new Account(id: $id);
- $old_account->Load();
- $new_account = new Account(
- id: $id,
- username: $old_account->username,
- password: $old_account->password,
- picture_hash: $picture_hash ?? $old_account->picture_hash,
- verified: $old_account->verified,
- bio: $bio ?? $old_account->bio,
- );
- CORSHelper();
- $new_account->Update();
- return api_json([
- "id" => $new_account->id,
- "username" => $new_account->username,
- "pictureHash" => $new_account->picture_hash,
- "bio" => $new_account->bio,
- "verified" => $new_account->verified,
- ]);
- }
- public static function addLink(): string
- {
- if(!signed_in(request())) throw new UnauthenticatedException(0, 401);
- $account_id = get_token_id(request());
- $link = input("link");
- $link_type = input("linkType");
- $link_enum_type = LinkEnum::tryFrom($link_type);
- // todo: add enum type filtering
- $link = new Link(account_id: $account_id, type: $link_enum_type, url: $link);
- $link->Save();
- return api_json([
- "id" => $link->id,
- "url" => $link->url,
- "type" => $link->type->value,
- "account_id" => $link->account_id
- ]);
- }
- public static function getFollowers($id): string {
- $followers = new Follow(followee_id: $id)->LoadMany();
- if(empty($followers)) throw new FollowNotFoundException(0, 404);
- for ($i = 0; $i < count($followers); $i++) {
- $follower = $followers[$i]["follower_id"];
- $account = new Account(id: $follower);
- $account->Load();
- $followers[$i] = [
- "followee_id" => (int)$id,
- "follower_id" => $follower,
- "username" => $account->username,
- "pictureHash" => $account->picture_hash,
- "verified" => $account->verified
- ];
- }
- return api_json($followers);
- }
- public static function getFollowing($id): string {
- $following = new Follow(follower_id: $id)->LoadMany();
- if(empty($following)) throw new FollowNotFoundException(0, 404);
- for ($i = 0; $i < count($following); $i++) {
- $followee = $following[$i]["followee_id"];
- $account = new Account(id: $followee);
- $account->Load();
- $following[$i] = [
- "followee_id" => $followee,
- "follower_id" => (int)$id,
- "username" => $account->username,
- "pictureHash" => $account->picture_hash,
- "verified" => $account->verified
- ];
- }
- return api_json($following);
- }
- public static function RegisterRoutes(): void
- {
- SimpleRouter::group([
- "prefix" => "/account/",
- ], function () {
- SimpleRouter::get("/availablePremiumProfilePictures", [AccountController::class, "getAvailablePremiumProfilePictures"]);
- SimpleRouter::get("/getPremiumProfilePicture/{id}", [AccountController::class, "getPremiumProfilePicture"]);
- SimpleRouter::get("/{id}/get", [AccountController::class, "getAccount"]);
- SimpleRouter::get("/{id}/videos", [AccountController::class, "getVideos"]);
- SimpleRouter::get("/{id}/picture", [AccountController::class, "getPicture"]);
- SimpleRouter::get("/{id}/followers", [AccountController::class, "getFollowers"]);
- SimpleRouter::get("/{id}/following", [AccountController::class, "getFollowing"]);
- SimpleRouter::post("/token", [AccountController::class, "getToken"]);
- SimpleRouter::post("/search", [AccountController::class, "search"]);
- SimpleRouter::post("/update", [AccountController::class, "updateAccount"]);
- SimpleRouter::post("/addLink", [AccountController::class, "addLink"]);
- SimpleRouter::options("/update", "CORSHelper");
- SimpleRouter::options("/token", "CORSHelper");
- });
- }
- }
|