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();
|
||||
},
|
||||
|
||||
'i11n' => function () {
|
||||
'i18n' => function () {
|
||||
global $path;
|
||||
return match ($path[2]) {
|
||||
'languages' => [
|
||||
|
|
|
@ -33,7 +33,7 @@ function format_bcid ($bcid): string
|
|||
$stripped_bcid = strtoupper($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);
|
||||
|
@ -46,10 +46,6 @@ function get_user_by_id($bcid) {
|
|||
function get_user_display_name($userId, $escape = true) {
|
||||
global $user;
|
||||
|
||||
if (!$_SESSION['auth']) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$target = array();
|
||||
if ($userId == $user['id']) {
|
||||
$target = $user;
|
||||
|
@ -73,6 +69,40 @@ function get_user_display_name($userId, $escape = true) {
|
|||
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') {
|
||||
global $path_raw;
|
||||
|
||||
|
@ -84,3 +114,13 @@ function requires_auth($redirect = '/auth/login') {
|
|||
header('Location: '.$redirect.'?callback='.urlencode($path_raw));
|
||||
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": {
|
||||
"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",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "959cf05207f5b0c9a0bc557d5387056c",
|
||||
"content-hash": "2630884c327f232fb79f8fcefae92fa4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bunnycdn/storage",
|
||||
|
@ -381,6 +381,235 @@
|
|||
],
|
||||
"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",
|
||||
"version": "1.0.3",
|
||||
|
|
68
index.php
68
index.php
|
@ -3,6 +3,7 @@
|
|||
$DOC_ROOT = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once $DOC_ROOT . '/vendor/autoload.php';
|
||||
use Intervention\Image\ImageManager;
|
||||
|
||||
// Includes
|
||||
try {
|
||||
|
@ -19,11 +20,18 @@ try {
|
|||
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 'common/strings.php';
|
||||
require_once 'common/account_utils.php';
|
||||
require_once 'common/validation.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
|
||||
// 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']) {
|
||||
$user = get_user_by_id($_SESSION['id']);
|
||||
$_SESSION['lang'] = $user['language'];
|
||||
}
|
||||
|
||||
$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 (array_key_exists('lang', $query)) {
|
||||
$_SESSION['lang'] = $query['lang'];
|
||||
location($path_raw);
|
||||
}
|
||||
|
||||
patch_lang($_SESSION['lang']);
|
||||
|
@ -79,6 +89,18 @@ patch_lang($_SESSION['lang']);
|
|||
|
||||
$routes = [
|
||||
'' => 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 () {
|
||||
global $path, $query;
|
||||
|
||||
|
@ -88,16 +110,20 @@ $routes = [
|
|||
require 'api.php'; /* Handoff further routing to API script. */
|
||||
},
|
||||
'auth' => function () {
|
||||
global $path, $query;
|
||||
global $path, $query, $flash;
|
||||
|
||||
if ($path[2] == 'signout') {
|
||||
require 'views/signedout.php';
|
||||
} else if ($path[2] == 'signup') {
|
||||
require 'views/signup.php';
|
||||
} else if ($path[2] == 'login') {
|
||||
require 'views/login.php';
|
||||
} else {
|
||||
return 404;
|
||||
switch ($path[2]) {
|
||||
case 'signout':
|
||||
require 'views/signedout.php';
|
||||
break;
|
||||
case 'signup':
|
||||
require 'views/signup.php';
|
||||
break;
|
||||
case 'login':
|
||||
require 'views/login.php';
|
||||
break;
|
||||
default:
|
||||
return 404;
|
||||
}
|
||||
exit();
|
||||
},
|
||||
|
@ -119,6 +145,13 @@ $routes = [
|
|||
if (isset($path[3])) {
|
||||
return 404;
|
||||
}
|
||||
|
||||
if ($path[2] == 'edit') {
|
||||
requires_auth();
|
||||
require 'views/profile_edit.php';
|
||||
return 200;
|
||||
}
|
||||
|
||||
$profile_owner = $path[2];
|
||||
$profile_owner = get_user_by_id($profile_owner);
|
||||
} else {
|
||||
|
@ -129,7 +162,20 @@ $routes = [
|
|||
return 200;
|
||||
},
|
||||
'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 script = document.scripts[document.scripts.length - 1];
|
||||
|
||||
const langs_req = fetch('/api/i11n/languages')
|
||||
const langs_req = fetch('/api/i18n/languages')
|
||||
.then(async data => {
|
||||
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 'ui.css';
|
||||
@import 'extra_icons.css';
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
|
@ -12,6 +14,8 @@ body {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background: var(--page-bg);
|
||||
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
@ -45,6 +49,20 @@ main {
|
|||
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 {
|
||||
flex: 0;
|
||||
|
||||
|
@ -126,3 +144,11 @@ body > .errorbox {
|
|||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-vertically {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
padding: 16px;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,17 @@
|
|||
/* ByeCorps ID colour scheme. Use on this site. */
|
||||
--black-bean: #330f0a;
|
||||
--dark-slate-gray: #394f49;
|
||||
--dark-slate-gray-dim: #536E65;
|
||||
--fern-green: #65743a;
|
||||
--flax: #efdd8d;
|
||||
--flax-dim: #BFB26E;
|
||||
--mindaro: #f4fdaf;
|
||||
|
||||
--white: #ffffff;
|
||||
--gray-0: #f8f9fa;
|
||||
--gray-1: #f1f3f5;
|
||||
--grey-5: #adb5bd;
|
||||
--gray-8: #343a40;
|
||||
--gray-9: #212529;
|
||||
|
||||
--red-2: #ffc9c9;
|
||||
|
@ -21,20 +25,35 @@
|
|||
--red-7: #f03e3e;
|
||||
--red-9: #c92a2a;
|
||||
|
||||
--ff-bg-black: #1a1a1a;
|
||||
|
||||
--page-bg: var(--white);
|
||||
|
||||
--link-fg: var(--dark-slate-gray);
|
||||
--non-color-link-fg: var(--gray-9);
|
||||
|
||||
--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);
|
||||
}
|
||||
|
||||
@media screen and (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--page-bg: var(--ff-bg-black);
|
||||
--link-fg: var(--flax);
|
||||
--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);
|
||||
--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;
|
||||
}
|
||||
|
||||
ul > li:has(.selected) {
|
||||
background: var(--selected-bg);
|
||||
}
|
||||
|
||||
ul > li:hover {
|
||||
background: var(--hover-bg);
|
||||
background: var(--hover-bg) !important;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-gap: 1rem;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
grid-template-columns: minmax(400px, 1fr) 3fr;
|
||||
}
|
||||
|
||||
|
||||
.id-card {
|
||||
align-self: center;
|
||||
background: var(--hover-bg);
|
||||
|
@ -36,3 +41,40 @@ ul > li:hover {
|
|||
.id-card > img {
|
||||
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>
|
||||
<div class="grid">
|
||||
<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="display_name"><?= get_user_display_name($_SESSION['id']) ?></div>
|
||||
<div class="id"><?= format_bcid($_SESSION['id']) ?></div>
|
||||
|
@ -31,12 +31,6 @@
|
|||
<div class="label"><?= get_string('page.settings') ?></div>
|
||||
</a>
|
||||
</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>
|
||||
<a href="/auth/signout" class="item">
|
||||
<div class="icon"><span class="fa-fw fa-solid fa-right-to-bracket"></span></div>
|
||||
|
|
|
@ -8,7 +8,17 @@
|
|||
<?php include 'partials/header.php'; ?>
|
||||
|
||||
<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>
|
||||
|
||||
<?php include 'partials/footer.php'; ?>
|
||||
|
|
|
@ -10,6 +10,11 @@ if ($_SESSION['auth']) {
|
|||
}
|
||||
|
||||
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
|
||||
$user_to_log_in_as = db_execute('SELECT id, email, password FROM accounts WHERE email = ?', [$_POST['email']]);
|
||||
if (!$user_to_log_in_as) {
|
||||
|
@ -28,6 +33,10 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
}
|
||||
exit();
|
||||
}
|
||||
} else {
|
||||
if (key_exists('callback', $query)) {
|
||||
$subtitle = get_string('auth.logInToContinue');
|
||||
}
|
||||
}
|
||||
|
||||
skip:
|
||||
|
@ -38,6 +47,7 @@ skip:
|
|||
<html lang="en">
|
||||
<head>
|
||||
<?php include 'partials/head.php' ?>
|
||||
<link rel="stylesheet" href="/styles/login_form.css" />
|
||||
</head>
|
||||
<body>
|
||||
<?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)) {
|
||||
include 'partials/error.php';
|
||||
}
|
||||
?>
|
||||
<form method="post">
|
||||
<p><label for="email"><?= get_string("auth.email") ?></label>
|
||||
<input type="email" name="email" id="email" /></p>
|
||||
<p><label for="password"><?= get_string("auth.password") ?></label>
|
||||
<input type="password" name="password" id="password" /></p>
|
||||
?>
|
||||
<form class="login-form" method="post">
|
||||
<div class="input"><label for="email"><?= get_string("auth.email") ?></label>
|
||||
<input type="email" name="email" id="email" /></div>
|
||||
<div class="input"><label for="password"><?= get_string("auth.password") ?></label>
|
||||
<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>
|
||||
|
||||
<?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>
|
||||
<?php
|
||||
if ($error) {
|
||||
if (isset($error)) {
|
||||
include 'partials/error.php';
|
||||
include 'partials/footer.php';
|
||||
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>
|
||||
|
||||
<?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