mirror of https://github.com/byecorps/id.git
i dont know whats in this
This commit is contained in:
parent
5174c30cec
commit
19c32f0a71
2
api.php
2
api.php
|
@ -8,7 +8,7 @@ $routes = [
|
||||||
exit();
|
exit();
|
||||||
},
|
},
|
||||||
|
|
||||||
'i11n' => function () {
|
'i18n' => function () {
|
||||||
global $path;
|
global $path;
|
||||||
return match ($path[2]) {
|
return match ($path[2]) {
|
||||||
'languages' => [
|
'languages' => [
|
||||||
|
|
|
@ -33,7 +33,7 @@ function format_bcid ($bcid): string
|
||||||
$stripped_bcid = strtoupper($stripped_bcid);
|
$stripped_bcid = strtoupper($stripped_bcid);
|
||||||
|
|
||||||
if (!validate_bcid($stripped_bcid)) {
|
if (!validate_bcid($stripped_bcid)) {
|
||||||
throw new Exception('Invalid BCID.');
|
return '999-9999';
|
||||||
}
|
}
|
||||||
|
|
||||||
return substr($stripped_bcid, 0, 3).'-'.substr($stripped_bcid, -4, 4);
|
return substr($stripped_bcid, 0, 3).'-'.substr($stripped_bcid, -4, 4);
|
||||||
|
@ -46,10 +46,6 @@ function get_user_by_id($bcid) {
|
||||||
function get_user_display_name($userId, $escape = true) {
|
function get_user_display_name($userId, $escape = true) {
|
||||||
global $user;
|
global $user;
|
||||||
|
|
||||||
if (!$_SESSION['auth']) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$target = array();
|
$target = array();
|
||||||
if ($userId == $user['id']) {
|
if ($userId == $user['id']) {
|
||||||
$target = $user;
|
$target = $user;
|
||||||
|
@ -73,6 +69,40 @@ function get_user_display_name($userId, $escape = true) {
|
||||||
return $display_name;
|
return $display_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_user_avatar($userId) {
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
if (!$_SESSION['auth']) {
|
||||||
|
return 'https://cdn.id.byecorps.com/profile/default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
$target = array();
|
||||||
|
if ($userId == $user['id']) {
|
||||||
|
$target = $user;
|
||||||
|
} else {
|
||||||
|
$target = get_user_by_id($userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$avatar = db_execute('SELECT * FROM avatars JOIN neo_id.files f on f.id = avatars.file_id WHERE avatars.owner = ?',
|
||||||
|
[ $target['id'] ]);
|
||||||
|
|
||||||
|
if ($avatar) {
|
||||||
|
// echo '<pre>'; print_r($avatar); echo '</pre>';
|
||||||
|
return 'https://cdn.id.byecorps.com/' . $avatar['path'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'https://cdn.id.byecorps.com/profile/default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_user_language(string $lang_code, string $id): void
|
||||||
|
{
|
||||||
|
db_execute(
|
||||||
|
'UPDATE accounts SET language = ? WHERE id = ?',
|
||||||
|
[$lang_code, $id]
|
||||||
|
);
|
||||||
|
$_SESSION['lang'] = $lang_code;
|
||||||
|
}
|
||||||
|
|
||||||
function requires_auth($redirect = '/auth/login') {
|
function requires_auth($redirect = '/auth/login') {
|
||||||
global $path_raw;
|
global $path_raw;
|
||||||
|
|
||||||
|
@ -84,3 +114,13 @@ function requires_auth($redirect = '/auth/login') {
|
||||||
header('Location: '.$redirect.'?callback='.urlencode($path_raw));
|
header('Location: '.$redirect.'?callback='.urlencode($path_raw));
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requires_admin() {
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
if ($user['is_admin']) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use kornrunner\Blurhash\Blurhash;
|
||||||
|
|
||||||
|
function mime_to_extension($mime) {
|
||||||
|
return match ($mime) {
|
||||||
|
'image/gif' => '.gif',
|
||||||
|
'image/jpeg' => '.jpg',
|
||||||
|
'image/png' => '.png',
|
||||||
|
'image/webp' => '.webp',
|
||||||
|
default => ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Squishes an image into a 128x128 square, and converts it to JPEG
|
||||||
|
* if it is not a JPEG, PNG, WEBP or GIF.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function turn_image_into_avatar(string $path): array
|
||||||
|
{
|
||||||
|
$manager = new \Intervention\Image\ImageManager(
|
||||||
|
new \Intervention\Image\Drivers\Gd\Driver()
|
||||||
|
);
|
||||||
|
|
||||||
|
$image = $manager->read($path);
|
||||||
|
|
||||||
|
// Get mimetype
|
||||||
|
$mime = mime_content_type($path);
|
||||||
|
$filetype = mime_to_extension($mime);
|
||||||
|
|
||||||
|
$enc = $image->resize(width: 128, height: 128);
|
||||||
|
|
||||||
|
if ($filetype=='') {
|
||||||
|
$enc = $image->encodeByMediaType('image/webp');
|
||||||
|
$filetype = '.webp';
|
||||||
|
} else {
|
||||||
|
$enc = $image->encodeByMediaType();
|
||||||
|
}
|
||||||
|
|
||||||
|
$image_data = (string) $enc;
|
||||||
|
|
||||||
|
return [
|
||||||
|
"data" => $image_data,
|
||||||
|
"mime" => $enc->mimetype(),
|
||||||
|
'filetype' => $filetype
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_blurhash_for_image($image): string
|
||||||
|
{
|
||||||
|
// Copied shamelessly from https://github.com/kornrunner/php-blurhash
|
||||||
|
$width = imagesx($image);
|
||||||
|
$height = imagesy($image);
|
||||||
|
|
||||||
|
$pixels = [];
|
||||||
|
for ($y = 0; $y < $height; ++$y) {
|
||||||
|
$row = [];
|
||||||
|
for ($x = 0; $x < $width; ++$x) {
|
||||||
|
$index = imagecolorat($image, $x, $y);
|
||||||
|
$colors = imagecolorsforindex($image, $index);
|
||||||
|
|
||||||
|
$row[] = [$colors['red'], $colors['green'], $colors['blue']];
|
||||||
|
}
|
||||||
|
$pixels[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$components_x = 4;
|
||||||
|
$components_y = 3;
|
||||||
|
return Blurhash::encode($pixels, $components_x, $components_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload_file($filename, $target, $owner=null) {
|
||||||
|
global $bunny_client;
|
||||||
|
|
||||||
|
$bunny_client->upload($filename, $target);
|
||||||
|
|
||||||
|
// Get file mime time
|
||||||
|
$mime = mime_content_type($filename);
|
||||||
|
|
||||||
|
$blurhash = '';
|
||||||
|
if (str_starts_with('image/', $mime)) {
|
||||||
|
$blurhash = get_blurhash_for_image(imagecreatefromstring(file_get_contents($filename)));
|
||||||
|
}
|
||||||
|
|
||||||
|
db_execute(
|
||||||
|
'INSERT INTO files (path, uploader, blurhash) VALUES (?, ?, ?)',
|
||||||
|
[$target, $owner, $blurhash]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload_raw_data($data, $target, $owner=null) {
|
||||||
|
$filename = '/tmp/'.uniqid(more_entropy: true);
|
||||||
|
file_put_contents($filename, $data);
|
||||||
|
|
||||||
|
upload_file($filename, $target, $owner);
|
||||||
|
|
||||||
|
unlink($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Bunny\Storage\Exception
|
||||||
|
* @throws ImagickException
|
||||||
|
*/
|
||||||
|
function upload_avatar($data, $user): string
|
||||||
|
{
|
||||||
|
global $bunny_client;
|
||||||
|
|
||||||
|
$img = turn_image_into_avatar($data['tmp_name']);
|
||||||
|
|
||||||
|
$uuid = uniqid(prefix: 'avatar', more_entropy: true);
|
||||||
|
|
||||||
|
$remote_file_name = 'avatars/'.$uuid.$img['filetype'];
|
||||||
|
|
||||||
|
upload_raw_data($img['data'], $remote_file_name);
|
||||||
|
|
||||||
|
$file = db_execute('SELECT id FROM files WHERE path = ? LIMIT 1', [$remote_file_name]);
|
||||||
|
|
||||||
|
$existing_avatar = db_execute('SELECT * FROM avatars WHERE owner = ?', [$user['id']]);
|
||||||
|
|
||||||
|
if (empty($existing_avatar)) {
|
||||||
|
db_execute(
|
||||||
|
'INSERT INTO avatars (file_id, owner) VALUES (?, ?)',
|
||||||
|
[$file['id'], $user['id']]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
db_execute(
|
||||||
|
'UPDATE avatars SET file_id = ? WHERE owner = ?',
|
||||||
|
[$file['id'], $user['id']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'https://'.BUNNY_STORAGE_ZONE.'.b-cdn.net/'.$remote_file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id int
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function delete_file_by_id(int $id): void
|
||||||
|
{
|
||||||
|
global $bunny_client;
|
||||||
|
|
||||||
|
// Get remote path
|
||||||
|
$file = db_execute('select * from files where id = ?', [$id]);
|
||||||
|
|
||||||
|
if (empty($file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove reference to the file in the database
|
||||||
|
db_execute('delete from files where id = ?', [$id]);
|
||||||
|
// Then remove the file
|
||||||
|
$bunny_client->delete($file['path']);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects to $url.
|
||||||
|
*
|
||||||
|
* @param $url string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function location(string $url):void
|
||||||
|
{
|
||||||
|
header('Location: '. $url);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash(string $text, string $type, array &$flash) {
|
||||||
|
$flash[] = ['text' => $text, 'type' => $type];
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function validate_email($email) {
|
||||||
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password rules:
|
||||||
|
* - At least 8 characters long
|
||||||
|
* That's it
|
||||||
|
*/
|
||||||
|
function validate_password($password) {
|
||||||
|
$password_min_length = 8;
|
||||||
|
if (strlen($password) >= $password_min_length) {
|
||||||
|
return $password;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -1,5 +1,11 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"bunnycdn/storage": "^3.3"
|
"bunnycdn/storage": "^3.3",
|
||||||
|
"kornrunner/blurhash": "^1.2",
|
||||||
|
"lbuchs/webauthn": "^2.2",
|
||||||
|
"intervention/image": "^3.7",
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-imagick": "*",
|
||||||
|
"ext-fileinfo": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "959cf05207f5b0c9a0bc557d5387056c",
|
"content-hash": "2630884c327f232fb79f8fcefae92fa4",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bunnycdn/storage",
|
"name": "bunnycdn/storage",
|
||||||
|
@ -381,6 +381,235 @@
|
||||||
],
|
],
|
||||||
"time": "2023-12-03T20:05:35+00:00"
|
"time": "2023-12-03T20:05:35+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "intervention/gif",
|
||||||
|
"version": "4.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Intervention/gif.git",
|
||||||
|
"reference": "3a2b5f8a8856e8877cdab5c47e51aab2d4cb23a3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Intervention/gif/zipball/3a2b5f8a8856e8877cdab5c47e51aab2d4cb23a3",
|
||||||
|
"reference": "3a2b5f8a8856e8877cdab5c47e51aab2d4cb23a3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1",
|
||||||
|
"phpunit/phpunit": "^10.0",
|
||||||
|
"slevomat/coding-standard": "~8.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.8"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Intervention\\Gif\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Oliver Vogel",
|
||||||
|
"email": "oliver@intervention.io",
|
||||||
|
"homepage": "https://intervention.io/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Native PHP GIF Encoder/Decoder",
|
||||||
|
"homepage": "https://github.com/intervention/gif",
|
||||||
|
"keywords": [
|
||||||
|
"animation",
|
||||||
|
"gd",
|
||||||
|
"gif",
|
||||||
|
"image"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Intervention/gif/issues",
|
||||||
|
"source": "https://github.com/Intervention/gif/tree/4.1.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://paypal.me/interventionio",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/Intervention",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-03-26T17:23:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "intervention/image",
|
||||||
|
"version": "3.7.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Intervention/image.git",
|
||||||
|
"reference": "5451ff9f909c2fc836722e5ed6831b9f9a6db68c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Intervention/image/zipball/5451ff9f909c2fc836722e5ed6831b9f9a6db68c",
|
||||||
|
"reference": "5451ff9f909c2fc836722e5ed6831b9f9a6db68c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"intervention/gif": "^4.1",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "^1.6",
|
||||||
|
"phpstan/phpstan": "^1",
|
||||||
|
"phpunit/phpunit": "^10.0",
|
||||||
|
"slevomat/coding-standard": "~8.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.8"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-exif": "Recommended to be able to read EXIF data properly."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Intervention\\Image\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Oliver Vogel",
|
||||||
|
"email": "oliver@intervention.io",
|
||||||
|
"homepage": "https://intervention.io/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP image manipulation",
|
||||||
|
"homepage": "https://image.intervention.io/",
|
||||||
|
"keywords": [
|
||||||
|
"gd",
|
||||||
|
"image",
|
||||||
|
"imagick",
|
||||||
|
"resize",
|
||||||
|
"thumbnail",
|
||||||
|
"watermark"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Intervention/image/issues",
|
||||||
|
"source": "https://github.com/Intervention/image/tree/3.7.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://paypal.me/interventionio",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/Intervention",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-07-05T13:35:01+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kornrunner/blurhash",
|
||||||
|
"version": "v1.2.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/kornrunner/php-blurhash.git",
|
||||||
|
"reference": "bc8a4596cb0a49874f0158696a382ab3933fefe4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/kornrunner/php-blurhash/zipball/bc8a4596cb0a49874f0158696a382ab3933fefe4",
|
||||||
|
"reference": "bc8a4596cb0a49874f0158696a382ab3933fefe4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.3|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ocramius/package-versions": "^1.4|^2.0",
|
||||||
|
"phpstan/phpstan": "^0.12",
|
||||||
|
"phpunit/phpunit": "^9",
|
||||||
|
"vimeo/psalm": "^4.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"kornrunner\\Blurhash\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Boris Momčilović",
|
||||||
|
"email": "boris.momcilovic@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Pure PHP implementation of Blurhash",
|
||||||
|
"homepage": "https://github.com/kornrunner/php-blurhash",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/kornrunner/php-blurhash/issues",
|
||||||
|
"source": "https://github.com/kornrunner/php-blurhash.git"
|
||||||
|
},
|
||||||
|
"time": "2022-07-13T19:38:39+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lbuchs/webauthn",
|
||||||
|
"version": "v2.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lbuchs/WebAuthn.git",
|
||||||
|
"reference": "20adb4a240c3997bd8cac7dc4dde38ab0bea0ed1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/lbuchs/WebAuthn/zipball/20adb4a240c3997bd8cac7dc4dde38ab0bea0ed1",
|
||||||
|
"reference": "20adb4a240c3997bd8cac7dc4dde38ab0bea0ed1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"lbuchs\\WebAuthn\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Lukas Buchs",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A simple PHP WebAuthn (FIDO2) server library",
|
||||||
|
"homepage": "https://github.com/lbuchs/webauthn",
|
||||||
|
"keywords": [
|
||||||
|
"Authentication",
|
||||||
|
"webauthn"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/lbuchs/WebAuthn/issues",
|
||||||
|
"source": "https://github.com/lbuchs/WebAuthn/tree/v2.2.0"
|
||||||
|
},
|
||||||
|
"time": "2024-07-04T07:17:40+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/http-client",
|
"name": "psr/http-client",
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
|
|
68
index.php
68
index.php
|
@ -3,6 +3,7 @@
|
||||||
$DOC_ROOT = $_SERVER['DOCUMENT_ROOT'];
|
$DOC_ROOT = $_SERVER['DOCUMENT_ROOT'];
|
||||||
|
|
||||||
require_once $DOC_ROOT . '/vendor/autoload.php';
|
require_once $DOC_ROOT . '/vendor/autoload.php';
|
||||||
|
use Intervention\Image\ImageManager;
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
try {
|
try {
|
||||||
|
@ -19,11 +20,18 @@ try {
|
||||||
echo "<b>Critical error:</b> " . $e->getMessage() . "<br />Please contact the developers.";
|
echo "<b>Critical error:</b> " . $e->getMessage() . "<br />Please contact the developers.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bunny_client = new \Bunny\Storage\Client(BUNNY_ACCESS_KEY, BUNNY_STORAGE_ZONE, \Bunny\Storage\Region::STOCKHOLM);
|
||||||
|
|
||||||
require_once 'strings/en.php'; // This ensures strings will fall back to English if one is missing.
|
require_once 'strings/en.php'; // This ensures strings will fall back to English if one is missing.
|
||||||
|
|
||||||
require_once 'common/strings.php';
|
require_once 'common/strings.php';
|
||||||
require_once 'common/account_utils.php';
|
require_once 'common/validation.php';
|
||||||
require_once 'common/database.php';
|
require_once 'common/database.php';
|
||||||
|
require_once 'common/account_utils.php';
|
||||||
|
require_once 'common/files.php';
|
||||||
|
require_once 'common/misc.php';
|
||||||
|
|
||||||
|
$flash = [];
|
||||||
|
|
||||||
// Starts the session
|
// Starts the session
|
||||||
// TODO: write this to use the database to work across more than one server (e.g. don't use PHP sessions)
|
// TODO: write this to use the database to work across more than one server (e.g. don't use PHP sessions)
|
||||||
|
@ -42,6 +50,7 @@ $user = null;
|
||||||
|
|
||||||
if ($_SESSION['auth']) {
|
if ($_SESSION['auth']) {
|
||||||
$user = get_user_by_id($_SESSION['id']);
|
$user = get_user_by_id($_SESSION['id']);
|
||||||
|
$_SESSION['lang'] = $user['language'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$uri_string = $_SERVER['REQUEST_URI']; // `/foo/bar?bar=foo&foo=bar`
|
$uri_string = $_SERVER['REQUEST_URI']; // `/foo/bar?bar=foo&foo=bar`
|
||||||
|
@ -72,6 +81,7 @@ if (str_ends_with($path_raw, '/') && $path_raw != '/') {
|
||||||
// If there's a 'lang' query param, change the language!
|
// If there's a 'lang' query param, change the language!
|
||||||
if (array_key_exists('lang', $query)) {
|
if (array_key_exists('lang', $query)) {
|
||||||
$_SESSION['lang'] = $query['lang'];
|
$_SESSION['lang'] = $query['lang'];
|
||||||
|
location($path_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
patch_lang($_SESSION['lang']);
|
patch_lang($_SESSION['lang']);
|
||||||
|
@ -79,6 +89,18 @@ patch_lang($_SESSION['lang']);
|
||||||
|
|
||||||
$routes = [
|
$routes = [
|
||||||
'' => function () { require 'views/home.php'; },
|
'' => function () { require 'views/home.php'; },
|
||||||
|
'admin' => function () {
|
||||||
|
global $path, $query, $DOC_ROOT, $flash;
|
||||||
|
|
||||||
|
requires_auth();
|
||||||
|
requires_admin();
|
||||||
|
|
||||||
|
switch ($path[2]) {
|
||||||
|
default: return 404;
|
||||||
|
case 'files':
|
||||||
|
require 'views/admin/files.php';
|
||||||
|
}
|
||||||
|
},
|
||||||
'api' => function () {
|
'api' => function () {
|
||||||
global $path, $query;
|
global $path, $query;
|
||||||
|
|
||||||
|
@ -88,16 +110,20 @@ $routes = [
|
||||||
require 'api.php'; /* Handoff further routing to API script. */
|
require 'api.php'; /* Handoff further routing to API script. */
|
||||||
},
|
},
|
||||||
'auth' => function () {
|
'auth' => function () {
|
||||||
global $path, $query;
|
global $path, $query, $flash;
|
||||||
|
|
||||||
if ($path[2] == 'signout') {
|
switch ($path[2]) {
|
||||||
require 'views/signedout.php';
|
case 'signout':
|
||||||
} else if ($path[2] == 'signup') {
|
require 'views/signedout.php';
|
||||||
require 'views/signup.php';
|
break;
|
||||||
} else if ($path[2] == 'login') {
|
case 'signup':
|
||||||
require 'views/login.php';
|
require 'views/signup.php';
|
||||||
} else {
|
break;
|
||||||
return 404;
|
case 'login':
|
||||||
|
require 'views/login.php';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 404;
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
},
|
},
|
||||||
|
@ -119,6 +145,13 @@ $routes = [
|
||||||
if (isset($path[3])) {
|
if (isset($path[3])) {
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($path[2] == 'edit') {
|
||||||
|
requires_auth();
|
||||||
|
require 'views/profile_edit.php';
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
|
||||||
$profile_owner = $path[2];
|
$profile_owner = $path[2];
|
||||||
$profile_owner = get_user_by_id($profile_owner);
|
$profile_owner = get_user_by_id($profile_owner);
|
||||||
} else {
|
} else {
|
||||||
|
@ -129,7 +162,20 @@ $routes = [
|
||||||
return 200;
|
return 200;
|
||||||
},
|
},
|
||||||
'settings' => function () {
|
'settings' => function () {
|
||||||
require 'views/settings.php';
|
global $path, $flash, $user;
|
||||||
|
if (isset($path[2])) {
|
||||||
|
switch ($path[2]) {
|
||||||
|
default: return 404;
|
||||||
|
case 'security':
|
||||||
|
require 'views/settings_security.php';
|
||||||
|
break;
|
||||||
|
case 'region':
|
||||||
|
require 'views/settings_region.php';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
require 'views/settings.php';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const select = document.createElement('select');
|
const select = document.createElement('select');
|
||||||
const script = document.scripts[document.scripts.length - 1];
|
const script = document.scripts[document.scripts.length - 1];
|
||||||
|
|
||||||
const langs_req = fetch('/api/i11n/languages')
|
const langs_req = fetch('/api/i18n/languages')
|
||||||
.then(async data => {
|
.then(async data => {
|
||||||
return await data.json();
|
return await data.json();
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
const linksOfCurrentPage = document.querySelectorAll('a[href="'+window.location.pathname+'"]');
|
||||||
|
console.log(window.location.pathname)
|
||||||
|
for (let i = 0; i < linksOfCurrentPage.length; i++) {
|
||||||
|
console.log(linksOfCurrentPage[i])
|
||||||
|
linksOfCurrentPage[i].classList.add('selected');
|
||||||
|
}
|
2
strings
2
strings
|
@ -1 +1 @@
|
||||||
Subproject commit d9131afc20afc0bb4205990bb34f8c455ae81f8d
|
Subproject commit 66e3af2bab97bc80b247cf43944bcd5d6506719f
|
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
@import "colours.css";
|
@import "colours.css";
|
||||||
|
@import 'ui.css';
|
||||||
|
@import 'extra_icons.css';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
color-scheme: light dark;
|
color-scheme: light dark;
|
||||||
|
@ -12,6 +14,8 @@ body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
background: var(--page-bg);
|
||||||
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +49,20 @@ main {
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .logo {
|
||||||
|
height: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
flex: 0;
|
flex: 0;
|
||||||
|
|
||||||
|
@ -126,3 +144,11 @@ body > .errorbox {
|
||||||
.center {
|
.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-vertically {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
|
@ -7,13 +7,17 @@
|
||||||
/* ByeCorps ID colour scheme. Use on this site. */
|
/* ByeCorps ID colour scheme. Use on this site. */
|
||||||
--black-bean: #330f0a;
|
--black-bean: #330f0a;
|
||||||
--dark-slate-gray: #394f49;
|
--dark-slate-gray: #394f49;
|
||||||
|
--dark-slate-gray-dim: #536E65;
|
||||||
--fern-green: #65743a;
|
--fern-green: #65743a;
|
||||||
--flax: #efdd8d;
|
--flax: #efdd8d;
|
||||||
|
--flax-dim: #BFB26E;
|
||||||
--mindaro: #f4fdaf;
|
--mindaro: #f4fdaf;
|
||||||
|
|
||||||
|
--white: #ffffff;
|
||||||
--gray-0: #f8f9fa;
|
--gray-0: #f8f9fa;
|
||||||
--gray-1: #f1f3f5;
|
--gray-1: #f1f3f5;
|
||||||
--grey-5: #adb5bd;
|
--grey-5: #adb5bd;
|
||||||
|
--gray-8: #343a40;
|
||||||
--gray-9: #212529;
|
--gray-9: #212529;
|
||||||
|
|
||||||
--red-2: #ffc9c9;
|
--red-2: #ffc9c9;
|
||||||
|
@ -21,20 +25,35 @@
|
||||||
--red-7: #f03e3e;
|
--red-7: #f03e3e;
|
||||||
--red-9: #c92a2a;
|
--red-9: #c92a2a;
|
||||||
|
|
||||||
|
--ff-bg-black: #1a1a1a;
|
||||||
|
|
||||||
|
--page-bg: var(--white);
|
||||||
|
|
||||||
--link-fg: var(--dark-slate-gray);
|
--link-fg: var(--dark-slate-gray);
|
||||||
--non-color-link-fg: var(--gray-9);
|
--non-color-link-fg: var(--gray-9);
|
||||||
|
|
||||||
--hover-bg: var(--gray-1);
|
--hover-bg: var(--gray-1);
|
||||||
|
--selected-bg: var(--gray-0);
|
||||||
|
|
||||||
|
--input-bg: var(--gray-1);
|
||||||
|
|
||||||
|
--button-primary-bg: var(--flax);
|
||||||
|
--button-primary-hover-bg: var(--flax-dim);
|
||||||
|
|
||||||
--error-fg: var(--red-9);
|
--error-fg: var(--red-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (prefers-color-scheme: dark) {
|
@media screen and (prefers-color-scheme: dark) {
|
||||||
:root {
|
:root {
|
||||||
|
--page-bg: var(--ff-bg-black);
|
||||||
--link-fg: var(--flax);
|
--link-fg: var(--flax);
|
||||||
--non-color-link-fg: var(--gray-0);
|
--non-color-link-fg: var(--gray-0);
|
||||||
--hover-bg: var(--gray-9);
|
--hover-bg: var(--gray-8);
|
||||||
|
--selected-bg: var(--gray-9);
|
||||||
--error-fg: var(--red-3);
|
--error-fg: var(--red-3);
|
||||||
|
--input-bg: var(--gray-9);
|
||||||
|
--button-primary-bg: var(--dark-slate-gray);
|
||||||
|
--button-primary-hover-bg: var(--dark-slate-gray-dim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,21 @@ ul > li > a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul > li:has(.selected) {
|
||||||
|
background: var(--selected-bg);
|
||||||
|
}
|
||||||
|
|
||||||
ul > li:hover {
|
ul > li:hover {
|
||||||
background: var(--hover-bg);
|
background: var(--hover-bg) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 1rem;
|
grid-gap: 1rem;
|
||||||
grid-template-columns: 1fr 2fr;
|
grid-template-columns: minmax(400px, 1fr) 3fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.id-card {
|
.id-card {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
background: var(--hover-bg);
|
background: var(--hover-bg);
|
||||||
|
@ -36,3 +41,40 @@ ul > li:hover {
|
||||||
.id-card > img {
|
.id-card > img {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settingsthingy h3 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid.halfandhalf {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-selector {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-selector label {
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
background: var(--input-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.language-selector label:hover {
|
||||||
|
background: var(--selected-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 880px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px) {
|
||||||
|
.grid.halfandhalf {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
.fluent--person-passkey-48-filled {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill='%23000' d='M24 4c-5.523 0-10 4.477-10 10s4.477 10 10 10s10-4.477 10-10S29.523 4 24 4M12.25 28A4.25 4.25 0 0 0 8 32.249V33c0 3.755 1.942 6.567 4.92 8.38C15.85 43.163 19.786 44 24 44c3.716 0 7.216-.65 10-2.027v-7.489A9 9 0 0 1 30.055 28zm19.82 0A7 7 0 1 1 41 33.71V34l2.293 2.293a1 1 0 0 1 0 1.414L41 40l2.322 2.322a1 1 0 0 1 .03 1.384l-3.646 3.968a1 1 0 0 1-1.444.03l-1.97-1.969a1 1 0 0 1-.292-.707V33.326A7.01 7.01 0 0 1 32.07 28M41 26a2 2 0 1 0-4 0a2 2 0 0 0 4 0'/%3E%3C/svg%3E");
|
||||||
|
background-color: currentColor;
|
||||||
|
-webkit-mask-image: var(--svg);
|
||||||
|
mask-image: var(--svg);
|
||||||
|
-webkit-mask-repeat: no-repeat;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
-webkit-mask-size: 100% 100%;
|
||||||
|
mask-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fluent--person-passkey-32-filled {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23000' d='M16 16a7 7 0 1 0 0-14a7 7 0 0 0 0 14m-8.5 2A3.5 3.5 0 0 0 4 21.5v.5c0 2.393 1.523 4.417 3.685 5.793C9.859 29.177 12.802 30 16 30c2.718 0 5.25-.594 7.285-1.622v-5.067A5.78 5.78 0 0 1 20.735 18zm17.07 9.626v-5.06a4.5 4.5 0 1 1 3.215.248V23l1.474 1.474a.643.643 0 0 1 0 .91l-1.474 1.473l1.493 1.493a.643.643 0 0 1 .019.89l-2.344 2.55a.643.643 0 0 1-.928.02l-1.266-1.266a.64.64 0 0 1-.188-.454zm3.055-10.25a1.125 1.125 0 1 0-2.25 0a1.125 1.125 0 0 0 2.25 0'/%3E%3C/svg%3E");
|
||||||
|
background-color: currentColor;
|
||||||
|
-webkit-mask-image: var(--svg);
|
||||||
|
mask-image: var(--svg);
|
||||||
|
-webkit-mask-repeat: no-repeat;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
-webkit-mask-size: 100% 100%;
|
||||||
|
mask-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-48 {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-32 {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-24 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-16 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
|
max-width: 600px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form > * {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form > *[type=submit] {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passkey {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
form.mini-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--input-bg);
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input input {
|
||||||
|
all: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:has([data-com-onepassword-filled='light']) {
|
||||||
|
background-color: hsl(210, 100%, 93%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:has([data-com-onepassword-filled='dark']) {
|
||||||
|
background-color: rgb(36, 107, 179);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:has(:-internal-autofill-selected) {
|
||||||
|
background-color: light-dark(rgb(232, 240, 254), rgba(70, 90, 126, 0.4));
|
||||||
|
}
|
||||||
|
|
||||||
|
button, .button {
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin: 0 0.25rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
border: rgba(136, 136, 136, 0.3) 1px solid;
|
||||||
|
font-family: "Montserrat", system-ui, sans-serif;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary, .button.primary {
|
||||||
|
background: var(--button-primary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary:hover, .button.primary:hover {
|
||||||
|
background: var(--button-primary-hover-bg);
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (!requires_admin()) {exit;} // failsafe in case this file is opened from "not the index".
|
||||||
|
|
||||||
|
if (isset($query['delete'])) {
|
||||||
|
delete_file_by_id($query['delete']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = db_execute_all('SELECT * FROM files');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php include $DOC_ROOT.'/views/partials/head.php' ?>
|
||||||
|
<title>[A] Files ~> ByeCorps ID</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include $DOC_ROOT.'/views/partials/header.php' ?>
|
||||||
|
<main>
|
||||||
|
<h1>[ADMIN] Files</h1>
|
||||||
|
<p>There are <?= count($files) ?> files.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<?php
|
||||||
|
foreach ($files as $file) {
|
||||||
|
echo '<li>';
|
||||||
|
|
||||||
|
if ($file['blurhash']) {
|
||||||
|
echo '<img src="https://cdn.id.byecorps.com/'. $file['path'] .'" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<p><a href="https://cdn.id.byecorps.com/'.$file['path'].'">ID: '.$file['id'].' ~~ '.$file['path'].'</a></p>';
|
||||||
|
|
||||||
|
if ($file['uploader']) {
|
||||||
|
echo '<p>Owned by <b>'. get_user_display_name($file['uploader']) .'</b></p>';
|
||||||
|
} else {
|
||||||
|
echo '<p>No owner on file</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<p>Uploaded on <b>'. $file['uploaded_date'] .'</b></p>';
|
||||||
|
|
||||||
|
$avatar = db_execute('select * from avatars where file_id = ?', [$file['id']]);
|
||||||
|
if (!empty($avatar)) {
|
||||||
|
echo '<p>Is ' . get_user_display_name($avatar['owner']) . '\'s avatar</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<p>Options: <a href="?delete='. $file['id'] .'">Delete</a></p>';
|
||||||
|
|
||||||
|
echo '</li>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<?php include $DOC_ROOT.'/views/partials/footer.php' ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -11,7 +11,7 @@
|
||||||
<h1><?= get_string('page.dashboard') ?></h1>
|
<h1><?= get_string('page.dashboard') ?></h1>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="id-card">
|
<div class="id-card">
|
||||||
<img src="https://cdn.id.byecorps.com/profile/281G3NV" alt="" />
|
<img src="<?= get_user_avatar($_SESSION['id']); ?>" alt="<?= get_user_display_name($_SESSION['id']) ?>'s avatar" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="display_name"><?= get_user_display_name($_SESSION['id']) ?></div>
|
<div class="display_name"><?= get_user_display_name($_SESSION['id']) ?></div>
|
||||||
<div class="id"><?= format_bcid($_SESSION['id']) ?></div>
|
<div class="id"><?= format_bcid($_SESSION['id']) ?></div>
|
||||||
|
@ -31,12 +31,6 @@
|
||||||
<div class="label"><?= get_string('page.settings') ?></div>
|
<div class="label"><?= get_string('page.settings') ?></div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="/settings/apps" class="item">
|
|
||||||
<div class="icon"><span class="fa-fw fa-solid fa-lock"></span></div>
|
|
||||||
<div class="label"><?= get_string('page.manageAppAccess') ?></div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href="/auth/signout" class="item">
|
<a href="/auth/signout" class="item">
|
||||||
<div class="icon"><span class="fa-fw fa-solid fa-right-to-bracket"></span></div>
|
<div class="icon"><span class="fa-fw fa-solid fa-right-to-bracket"></span></div>
|
||||||
|
|
|
@ -8,7 +8,17 @@
|
||||||
<?php include 'partials/header.php'; ?>
|
<?php include 'partials/header.php'; ?>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<h1><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
|
<div class="hero">
|
||||||
|
<div class="hero-text">
|
||||||
|
<img src="https://cdn.id.byecorps.com/assets/bcid.svg" alt="ByeCorps ID Logo" class="logo">
|
||||||
|
<h1><span class="bc-1">Bye</span><span class="bc-2">Corps</span><span class="bc-3"> ID</span></h1>
|
||||||
|
<p>Log into ByeCorps and beyond with a single ID.</p>
|
||||||
|
<!-- <p><input type="email" name="loginEmail" id="loginEmail" placeholder="Email" /></p> -->
|
||||||
|
|
||||||
|
<a href="/auth/login" class="button primary"><?= get_string('auth.login') ?></a>
|
||||||
|
<a href="/auth/signup" class="button"><?= get_string('auth.signup') ?></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<?php include 'partials/footer.php'; ?>
|
<?php include 'partials/footer.php'; ?>
|
||||||
|
|
|
@ -10,6 +10,11 @@ if ($_SESSION['auth']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
// Validate email address
|
||||||
|
if (!validate_email($_POST['email'])) {
|
||||||
|
$error_body = get_string('error.invalidEmail');
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out if it's a user
|
// Figure out if it's a user
|
||||||
$user_to_log_in_as = db_execute('SELECT id, email, password FROM accounts WHERE email = ?', [$_POST['email']]);
|
$user_to_log_in_as = db_execute('SELECT id, email, password FROM accounts WHERE email = ?', [$_POST['email']]);
|
||||||
if (!$user_to_log_in_as) {
|
if (!$user_to_log_in_as) {
|
||||||
|
@ -28,6 +33,10 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
}
|
}
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (key_exists('callback', $query)) {
|
||||||
|
$subtitle = get_string('auth.logInToContinue');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
|
@ -38,6 +47,7 @@ skip:
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<?php include 'partials/head.php' ?>
|
<?php include 'partials/head.php' ?>
|
||||||
|
<link rel="stylesheet" href="/styles/login_form.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<?php include 'partials/header.php' ?>
|
<?php include 'partials/header.php' ?>
|
||||||
|
@ -49,20 +59,39 @@ skip:
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<h1><?= get_string('page.login') ?></h1>
|
|
||||||
<?php
|
<div id="wrapper">
|
||||||
|
<h1 class="center"><?= get_string('page.login') ?></h1>
|
||||||
|
<p class="center">Don't have one? <a href="/auth/signup">Sign up</a>.</p>
|
||||||
|
<?php
|
||||||
|
if (isset($subtitle)) {
|
||||||
|
echo '<p class="subtitle center">'. $subtitle .'</p>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
if (isset($error_body)) {
|
if (isset($error_body)) {
|
||||||
include 'partials/error.php';
|
include 'partials/error.php';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<form method="post">
|
<form class="login-form" method="post">
|
||||||
<p><label for="email"><?= get_string("auth.email") ?></label>
|
<div class="input"><label for="email"><?= get_string("auth.email") ?></label>
|
||||||
<input type="email" name="email" id="email" /></p>
|
<input type="email" name="email" id="email" /></div>
|
||||||
<p><label for="password"><?= get_string("auth.password") ?></label>
|
<div class="input"><label for="password"><?= get_string("auth.password") ?></label>
|
||||||
<input type="password" name="password" id="password" /></p>
|
<input type="password" name="password" id="password" /></div>
|
||||||
|
|
||||||
|
<button class="primary" type="submit"><?= get_string('auth.login') ?></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="passkey center">
|
||||||
|
<h2><span class="icon icon-32 align-vertically fluent--person-passkey-32-filled"></span>
|
||||||
|
<span class="label"><?= get_string('auth.passkey') ?></span></h2>
|
||||||
|
<p><?= get_string('auth.logInWithPasskeyExplainer'); ?></p>
|
||||||
|
<p><button><?= get_string('auth.logInWithPasskey') ?></button></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</form>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<?php include 'partials/footer.php' ?>
|
<?php include 'partials/footer.php' ?>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/settings/account" class="item">
|
||||||
|
<div class="icon"><span class="fa-fw fa-solid fa-user"></span></div>
|
||||||
|
<span class="label"><?= get_string('settings.account') ?></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/settings/region" class="item">
|
||||||
|
<div class="icon"><span class="fa-fw fa-solid fa-globe"></span></div>
|
||||||
|
<span class="label"><?= get_string('settings.region') ?></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/settings/security" class="item">
|
||||||
|
<div class="icon"><span class="fa-fw fa-solid fa-lock"></span></div>
|
||||||
|
<div class="label"><?= get_string('settings.security') ?></div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<script src="/scripts/settings_list_assister.js" async></script>
|
|
@ -18,14 +18,22 @@ if (is_null($user)) {
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<?php
|
<?php
|
||||||
if ($error) {
|
if (isset($error)) {
|
||||||
include 'partials/error.php';
|
include 'partials/error.php';
|
||||||
include 'partials/footer.php';
|
include 'partials/footer.php';
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<p><?= $profile_owner['id'] ?></p>
|
|
||||||
|
|
||||||
|
<div id="profile-wrapper">
|
||||||
|
<img id="profile-image"
|
||||||
|
src="<?= get_user_avatar($profile_owner['id']) ?>"
|
||||||
|
alt="<?= get_user_display_name($profile_owner['id']) ?>'s avatar" />
|
||||||
|
<div id="profile-user-info">
|
||||||
|
<span id="profile-display-name"><?= get_user_display_name($profile_owner['id']) ?></span>
|
||||||
|
<span id="profile-bcid"><?= format_bcid($profile_owner['id']) ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<?php include 'partials/footer.php' ?>
|
<?php include 'partials/footer.php' ?>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
$mime_avatar = mime_content_type($_FILES['avatar']['tmp_name']);
|
||||||
|
if (str_contains($mime_avatar, 'image')) {
|
||||||
|
echo $mime_avatar;
|
||||||
|
$new_avatar = upload_avatar($_FILES['avatar'], $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// location('/profile');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<?php include "partials/head.php" ?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include "partials/header.php" ?>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<h1>Editing profile</h1>
|
||||||
|
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Images</legend>
|
||||||
|
|
||||||
|
<label for="avatar">Avatar</label>
|
||||||
|
<input type="file" accept="image/*" name="avatar" id="avatar" />
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<button type="submit"><?= get_string('button.submit') ?></button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php include 'partials/footer.php' ?>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php require 'partials/head.php'; ?>
|
||||||
|
<title><?= get_string('page.settings'); ?> ~> ByeCorps ID </title>
|
||||||
|
<link rel="stylesheet" href="/styles/dashboard.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include "partials/header.php" ?>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1><span class="fa-solid fa-fw fa-cog"></span> <?= get_string('page.settings'); ?></h1>
|
||||||
|
<?php include 'partials/settings_list.php' ?>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php include 'partials/footer.php' ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function update_language(): void
|
||||||
|
{
|
||||||
|
global $user;
|
||||||
|
set_user_language($_POST['lang'], $user['id']);
|
||||||
|
location('/settings/region');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($path[3])) {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
switch ($path[3]) {
|
||||||
|
case 'set_language':
|
||||||
|
update_language();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
location('/settings/region');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
location('/settings/region');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php require 'partials/head.php'; ?>
|
||||||
|
<title><?= get_string('page.settings'); ?> ~> ByeCorps ID </title>
|
||||||
|
<link rel="stylesheet" href="/styles/dashboard.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include "partials/header.php" ?>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1><span class="fa-solid fa-fw fa-cog"></span> <?= get_string('page.settings'); ?></h1>
|
||||||
|
<div class="grid">
|
||||||
|
<?php include 'partials/settings_list.php' ?>
|
||||||
|
<div class="settingsthingy">
|
||||||
|
<h2><?= get_string('settings.region') ?></h2>
|
||||||
|
<p>Here you can set the language ByeCorps ID is displayed in.</p>
|
||||||
|
<form action="/settings/region/set_language" method="post">
|
||||||
|
<div class="language-selector">
|
||||||
|
<?php
|
||||||
|
foreach (LANGAUGES as $lang) {
|
||||||
|
$checked = '';
|
||||||
|
if ($lang['code'] == $_SESSION['lang']) {
|
||||||
|
$checked = 'checked="checked"';
|
||||||
|
}
|
||||||
|
echo '<label>
|
||||||
|
<input type="radio" name="lang" '.$checked.' id="lang" value="'. $lang['code'] . '" />
|
||||||
|
'. $lang['name'] .'
|
||||||
|
</label>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<button class='primary' type="submit"><?= get_string('button.submit') ?></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php include 'partials/footer.php' ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php require 'partials/head.php'; ?>
|
||||||
|
<title><?= get_string('page.settings'); ?> ~> ByeCorps ID </title>
|
||||||
|
<link rel="stylesheet" href="/styles/dashboard.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include "partials/header.php" ?>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1><span class="fa-solid fa-fw fa-cog"></span> <?= get_string('page.settings'); ?></h1>
|
||||||
|
<div class="grid">
|
||||||
|
<?php include 'partials/settings_list.php' ?>
|
||||||
|
<div class="settingsthingy">
|
||||||
|
<h2><?= get_string('settings.security') ?></h2>
|
||||||
|
<h3><?= get_string('auth.password') ?></h3>
|
||||||
|
<form class="settings-grid mini-form" method="post">
|
||||||
|
<div class="input">
|
||||||
|
<label for="current-password"><?= get_string('auth.currentPassword') ?></label>
|
||||||
|
<input type="password" name="current-password" id="current-password" autocomplete="current-password" />
|
||||||
|
</div>
|
||||||
|
<div class="input">
|
||||||
|
<label for="new-password"><?= get_string('auth.newPassword') ?></label>
|
||||||
|
<input type="password" name="new-password" id="new-password" autocomplete="new-password" />
|
||||||
|
</div>
|
||||||
|
<div class="input">
|
||||||
|
<label for="confirm-password"><?= get_string('auth.confirmPassword') ?></label>
|
||||||
|
<input type="password" name="confirm-password" id="confirm-password" autocomplete="new-password" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit"><?= get_string('button.changePassword') ?></button>
|
||||||
|
</form>
|
||||||
|
<form action="/settings/security/passkey" method="post" class="settings-grid">
|
||||||
|
<h3><span class="icon icon-24 align-vertically fluent--person-passkey-32-filled center"></span> <?= get_string('auth.passkeyPlural') ?></h3>
|
||||||
|
<div class="grid halfandhalf">
|
||||||
|
<div class="item">
|
||||||
|
<p>Passkeys allow you to log in to ByeCorps ID using your device instead of a password.</p>
|
||||||
|
<button id="add_passkey">Add a passkey</button>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<?= get_string('settings.passkeysCountNone') ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<?php include 'partials/footer.php' ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue